第3章 抽象類
當編寫一個類時,我們往往會為該類定義一些方法,這些方法是用來描述該類的功能具體實現方式,那麽這些方法都有具體的方法體。
但是有的時候,某個父類只是知道子類應該包含怎麽樣的方法,但是無法準確知道子類如何實現這些方法。比如一個圖形類應該有一個求周長的方法,但是不同的圖形求周長的算法不一樣。那該怎麽辦呢?
分析事物時,發現了共性內容,就出現向上抽取。會有這樣一種特殊情況,就是方法功能聲明相同,但方法功能主體不同。那麽這時也可以抽取,但只抽取方法聲明,不抽取方法主體。那麽此方法就是一個抽象方法。
1.1.1 案例代碼十一:
package com.itheima_01; /* * abstract:關鍵字,用於修飾方法和類 * 抽象方法:不同類的方法是相似,但是具體內容又不太一樣,所以我們只能抽取他的聲明,沒有具體的方法體,沒有具體方法體的方法就是抽象方法 * 抽象類:有抽象方法的類必須是抽象類 * * 註意:一個類繼承了抽象類需要重寫他所有的抽象方法,否則這個類就得是抽象類 */ public class AbstractDemo { } abstract class Animal1 { public abstract void eat(); //非抽象方法子類可以不重寫 public void run() { } } class Cat1 extends Animal1 { @Override public void eat() { System.out.println("貓吃魚"); } /*public void eat() { System.out.println("貓吃魚"); }*/ } abstract class Dog1 extends Animal1 { /*public void eat() { System.out.println("狗吃屎"); }*/ }
1.2 抽象類的特點
抽象類的特點:
抽象方法只能在抽象類裏面
抽象類和抽象方法必須被abstract修飾
抽象類不能創建對象(不能實例化)
抽象類中可以有非抽象的方法
抽象類和類的關系也是繼承
一個類繼承了抽象類要麽重寫所有的抽象方法,要麽他自己是抽象類
1.2.1 案例代碼十二
package com.itheima_01; /* * 抽象類的特點: * 抽象方法只能在抽象類裏面 * 抽象類和抽象方法必須被abstract修飾 * 抽象類不能創建對象(不能實例化) * 抽象類中可以有非抽象的方法 * 抽象類和類的關系也是繼承 * 一個類繼承了抽象類要麽重寫所有的抽象方法,要麽他自己是抽象類 */ public class AbstractDemo2 { public static void main(String[] args) { //Animal a = new Animal(); } } abstract class Animal2 { public abstract void eat(); public void run() { } } class Cat2 extends Animal2 { @Override public void eat() { // TODO Auto-generated method stub } }
1.3 抽象類的成員的特點
A:抽象類的成員特點:
成員變量
可以有成員變量
可以有常量
成員方法
可以有抽象方法
可以有非抽象方法
構造方法
可以有構造方法的,需要對抽象類的成員變量進行初始化
1.3.1 案例代碼十三
package com.itheima_01; /* * 抽象類的成員特點: * 成員變量 * 可以有成員變量 * 可以有常量 * 成員方法 * 可以有抽象方法 * 可以有非抽象方法 * 構造方法 * 可以有構造方法的,需要對抽象類的成員變量進行初始化 * * final:修飾類、成員變量、成員方法 */ public class AbstractDemo3 { public static void main(String[] args) { Dog d = new Dog(); d.barking(); } } abstract class Animal { String name = "哮天犬"; final int num = 10; public Animal() { System.out.println("我是抽象類的構造方法"); } public abstract void eat(); public void run() {} } class Dog extends Animal { public void barking() { System.out.println(name); System.out.println(num); } @Override public void eat() { // TODO Auto-generated method stub } }
1.4 抽象類案例
1.4.1 老師案例:
老師類:
屬性:姓名,年齡,性別
行為:講課
基礎班老師:
屬性:姓名,年齡,性別
行為:講基礎班課程
就業班老師:
屬性:姓名,年齡,性別
行為:講就業班課程
1.4.1.1 案例代碼十四
//測試類
package com.itheima_04;
/*
* 基礎班老濕,就業班老濕
共性
屬性 姓名,年齡,性別
行為 講課
*
*/
public class AbstractTest {
public static void main(String[] args) {
//創建的基礎班老濕對象
BasicTeacher bt = new BasicTeacher();
//為老濕對象的成員變量進行賦值
bt.setName("風清揚");
bt.setAge(50);
bt.setGender("男");
bt.teach();
//創建就業班老濕對象
JobTeacher jt = new JobTeacher();
//為老濕對象的成員變量進行賦值
jt.setName("蒼老師");
jt.setAge(18);
jt.setGender("女");
jt.teach();
}
}
package com.itheima_04;
//老師類
public abstract class Teacher {
private String name;//姓名
private int age;//年齡
private String gender;//性別
public Teacher() {
super();
// TODO Auto-generated constructor stub
}
public Teacher(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public abstract void teach();
}
package com.itheima_04;
//基礎班老師類
public class BasicTeacher extends Teacher {
@Override
public void teach() {
System.out.println(getName() + "講基礎班課程");
}
}
package com.itheima_04;
//就業班老師類
public class JobTeacher extends Teacher{
@Override
public void teach() {
System.out.println(getName() + "講就業班課程");
}
}
1.4.2 員工案例
雇員類:
屬性:姓名,編號,薪水
行為:工作
程序員:
屬性:姓名,編號,薪水
行為:寫代碼工作
經理:
屬性:姓名,編號,薪水,獎金
行為:盯著程序員寫代碼工作
1.4.2.1 案例代碼十五
//測試類
package com.itheima_05;
/*
* 員工(Employee)示例:
需求:
公司中
程序員(Programmer)有姓名(name),工號(id),薪水(pay),工作(work)。
項目經理(Manager)除了有姓名(name),工號(id),薪水(pay),工作(work),還有獎金(bonus)。
共性
屬性 姓名,工號,薪水
行為 工作
*/
public class AbstractTest2 {
public static void main(String[] args) {
//創建程序員對象
Programmer p = new Programmer();
p.setName("張三");
p.setId("002");
p.setPay(10000);
p.work();
//創建項目經理的對象
Manager m = new Manager();
m.setName("比爾蓋茨");
m.setId("001");
m.setPay(0);
m.setBonus((byte)100);
m.work();
}
}
//員工類
package com.itheima_05;
public abstract class Employee {
private String name;//姓名
private String id;//工號
private double pay;//薪水
public Employee() {
super();
// TODO Auto-generated constructor stub
}
public Employee(String name, String id, double pay) {
super();
this.name = name;
this.id = id;
this.pay = pay;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public double getPay() {
return pay;
}
public void setPay(double pay) {
this.pay = pay;
}
public abstract void work();
}
//程序員類
package com.itheima_05;
public class Programmer extends Employee {
@Override
public void work() {
System.out.println(getName() + "正在寫代碼...");
}
}
//項目經理類
package com.itheima_05;
public class Manager extends Employee{
private byte bonus;
public byte getBonus() {
return bonus;
}
public void setBonus(byte bonus) {
this.bonus = bonus;
}
@Override
public void work() {
System.out.println(getName() + "正在盯著程序員寫代碼...");
}
}
1.4.3 技師案例
技師:
屬性:姓名,年齡
行為:服務
足療技師:
屬性:姓名,年齡
行為:按按腳揉揉肩
其它技師:
屬性:姓名,年齡
行為:你懂的
1.4.3.1 案例代碼十六
//測試類
package com.itheima_06;
/*
* 足療店
* 技師
* 足療技師
* 其他技師
* 共性
* 屬性 姓名,年齡
* 行為 服務
*/
public class AbstractTest3 {
public static void main(String[] args) {
//創建足療技師的對象
足療技師 zl = new 足療技師();
zl.service();
//創建其他技師對象
其他技師 qt = new 其他技師();
qt.service();
}
}
//技師類
package com.itheima_06;
public abstract class 技師 {
private String name;//姓名
private int age;//年齡
public 技師() {
super();
// TODO Auto-generated constructor stub
}
public 技師(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public abstract void service();
}
//足療技師類
package com.itheima_06;
public class 足療技師 extends 技師{
@Override
public void service() {
System.out.println("揉揉肩按按腰捏捏腳");
}
[align=left]}
//其它技師類
package com.itheima_06;
public class 其他技師 extends 技師{
@Override
public void service() {
System.out.println("你懂的");
}
}
1.5 抽象類的細節
A:抽象類關鍵字abstract可以和哪些關鍵字共存?
1.private:
私有的方法子類是無法繼承到的,也不存在覆蓋,而abstract和private一起使用修飾方法,abstract既要子類去實現這個方法,而private修飾子類根本無法得到父類這個方法。互相矛盾。
2.final:
抽象類不能和final共存,因為抽象類自身無法創建對象,我們需要通過子類創建對象,一旦抽象類使用final關鍵字,那麽抽象類就沒有子類
抽象方法不能和final共存,因為抽象方法後期需要被子類重寫,一旦加final無法重寫
3.static:
抽象方法不能和static關鍵字共存,因為一旦加static我們就可以通過類名直接訪問抽象方法,由於抽象方法沒有方法體,沒有任何意義,也不允許這樣做
B:抽象類中是否可以不定義抽象方法?
是可以的,那這個抽象類的存在到底有什麽意義呢?不讓該類創建對象,方法可以直接讓子類去使用
C:抽象類是否有構造函數?
有,抽象類的構造函數,是由子類的super語句來調用,用於給抽象類中的成員初始化
第3章 抽象類