1、多态
1.1、概述
1.2、实现步骤
1.3、多态特点
1.4、多态中成员访问特点
1.5、多态中的转型
1、多态
1.1、概述
多态:同一个引用类型,使用不同的实例对象而产生不同的操作结果
1.2、实现步骤
- 父子继承关系,且多个子类重写了父类的某一个方法
- (调用方法中)父类的类型作为方法的形参类型,用形参调用父类的被重写方法
- 在实际调用时,以子类对象作为传入的实参。
- 能根据传入的子类类型,自动调用该类型中重写后的方法
//父类关键代码
public abstract class Pet {//抽象类
void play(){
if(this instanceof Dog){
Dog d=(Dog)this;
d.playPan();
d.show();
}else if(this instanceof Penguin){
Penguin p=(Penguin)this;
p.swim();
}
}
abstract void choseMaster();//抽象方法
void show(){
System.out.println("我是宠物类的父类");
}
}
//子类关键代码
public class Dog extends Pet {
@Override//方法重写的标识
void choseMaster() {
System.out.println("狗狗对你摇尾巴,");
}
void playPan(){
System.out.println("狗狗喜欢玩飞盘");
}
}
//调用类关键代码
public class Master {
void chosePet(Pet p){//父类的类型作为方法的形参类型
p.play();
}
public static void main(String[] args) {
Master m=new Master();
Pet p1=new Dog();//父类的引用变量怕p1指向子类对象
m.chosePet(p1);//在实际调用时,以子类对象作为传入的实参。
}
}
1.3、多态特点
可扩展性强,维护性高,代码数较少,提高了重用性,但耦合性高
1.4、多态中成员访问特点
- 成员变量:编译看左边,执行看左边
public class Son extends Father{
String hobby;
public static void main(String[] args) {
Father fs=new Son();
// fs.hobby="";//编译会报错,hobby是子类特有属性
fs.name="";//name属性在父类中有定义时不会报错
}
}
- 成员方法:编译看左边,执行看右边(由于成员方法有重写,成员变量没有)
public class Son extends Father{
public static void main(String[] args) {
Father fs=new Son();
fs.show();//当父类中有show()方法时而子类中没有时,编译不会报错,执行的是从父类继承过来的show()方法;当子类重写了父类中的show()方法时,执行就只是子类重写的show()方法了
}
}
1.5、多态中的转型
1.5.1、向上转型
大类型接收小类型,会默认转成大类型
格式:<父类型><引用变量名>=new<子类型>();
/*父类引用指向子类对象;
此时通过父类引用变量调用的是子类覆盖或继承父类的方法,不是父类的方法;
此时通过父类引用变量不能调用子类特有的方法。
*/
Pet pet=new Dog();//Pet是父类,Dog是子类
1.5.2、向下转型:
父类引用转为子类对象
Pet pet=new Dog();
Dog dog=(Dog)pet;//Pet是父类,Dog是子类,此时可以用dog来调用Dog类的特有方法以及继承的父类的成员
需要强制转换成小类型,但前提是这个大类型的实例确实是小类型(用instansof)
void play(){
if(this instanceof Dog){//当前对象是否是Dog类的实例
Dog d=(Dog)this;
d.playPan();
d.show();
}else if(this instanceof Penguin){//当前对象是否是Penguin类的实例
Penguin p=(Penguin)this;
p.swim();
}
}
2、抽象:abstract关键字
当类不需要实例化时,在class关键字前机上abstract关键字,变为抽象类;
且当方法不需要方法体时,在返回值类型前加abstract,变为抽象方法;
public abstract class Pet {//抽象类
//结构体
}
abstract void choseMaster();//抽象方法
抽象类:不能被实例化;抽象类中可以有抽象方法,也可以没有抽象方法;
抽象方法:抽象方法必须被定义在抽象类中;抽象方法没有方法体;抽象方法必须在子类中被实现,除非子类是抽象类