多 态
多 态
1. 概述:同一个对象,在不同时刻表现出来的不同形态。
比如:猫是猫,猫是动物
猫 cat=new 猫();
也可以说猫是动物 动物 animal=new 猫();
猫在不同时刻表现出不同形态就是多态。
l 多态的前提和体现:
有继承、实现关系
有方法重写
有父类引用指向子类对象 如:动物 Animal=new 猫();
2. 多态中成员访问特点
l 成员变量:编译看左边,执行看左边。
l 成员方法:编译看左边,执行看右边。
Animal a = new Cat();
System.out.println(a.age);//成员变量编译看左边,执行看右边
a.eat();//成员方法编译看左边,执行看右边
为什么成员方法和成员变量的访问方式不一样呢?
l 因为成员方法有重写,而变量没有。
3. 多态的好处和弊端
好处:提高了程序的扩展性
具体体现:定义方法时,用父类型作为参数,在使用的时候,用子类型参与操作。
弊端:
不能使用子类的特有功能
c.eat(); //而吃是大家都有的功能
c.lookDoor(); //弊端:不能使用子类的特有功能。看门是子类狗特有的功能。
4. 多态中的转型
可以实现使用子类的特有功能
转型分类:
l 向上转型 Animal a=new Cat(); 把子类向上赋值给父类
从子到父
父类引用指向子类对象。
l 向下转型 Cat c=(Cat)a;// 父类引用转为子类对象
c.playGame //这样就可以使用子类特有的功能
从父到子
父类引用转为子类对象。
5. 猫狗案例多态版
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}
public class Dog extends Animal {
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}
public class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
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 void eat(){
System.out.println("动物吃饭");
}
}
package itheima01;
//猫和狗案例多态版
/**
* @author murongkang
* @date 2019-08-26 18:07
*/
public class AnimaDemo {
public static void main(String[] args) {
//创建猫对象并测试
Animal c = new Cat(); //无参
c.setAge(23);
c.setName("加菲猫");
c.eat();
System.out.println(c.getName() + c.getAge());
c=new Cat("加菲猫",22); //猫的有参
c.eat();
System.out.println(c.getName()+c.getAge());
//创建狗对象并测试
Animal d=new Dog("劫匪狗",33); //用有参
d.eat();
System.out.println(d.getName()+d.getAge());
}
}
6. 抽象类
概述:抽象类里面有抽象方法,抽象方法里面没有方法体。
抽象方法必须在抽象类中,也就是在方法和类前都要加abstract。
public abstract class Animal { //抽象类
public abstract void eat(); //抽象方法
}
public class AnimalDemo {
public static void main(String[] args) {
Animal a=new Animal() ; //报错,抽象类如何创建对象?
}
}
7. 抽象类特点:
l 抽象类里面可以没有抽象方法
l 有抽象方法,就一定有抽象类
l 抽象类和抽象方法必须使用abstract关键字。
l 抽象类不能实例化:参照多态方式,通过子类对象实例化,这叫抽象类多态。
l 抽象类的子类
要么重写抽象类中的所有抽象方法,要么是抽象类。
8. 抽象类的成员特点
l 成员变量
可以是变量、也可以是常量
l 构造方法
有构造方法,但不能实例化。那么,构造方法的作用?用于子类访问父类数据的初始化
l 成员方法
可以有抽象方法:限定子类必须完成某动作。
也可以有非抽象方法:提高代码复用性。(由继承保证)
9. 猫和狗的抽象类版
10. 接口
概述:接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用。
Java中的接口更多体现在对行为的抽象。
11. 接口的特点
接口实例化也采用多态形式
l 接口用关键字interface修饰
public interface JieKou {
public abstract void jump();
}
l 类实现接口用implements表示
public class Cat implements JieKou{
@Override
public void jump() {
System.out.println("猫可以跳高了");
}
}
l 接口不能实例化:
接口实现实例化通过多态的方式,通过实现类对象实例化,这叫接口的多态。
多态的形式:具体类多态、抽象类多态、接口多态。
多态的前提:有继承或者实现关系;有方法重写;有父(类/接口)引用指向(子/实现)类对象。
l 接口的实现类:
要么重写接口中的所有抽象方法、要么是抽象类。
接口中的变量是常量,并且默认静态修饰,成员变量可以通过接口名直接访问。
12.接口的成员特点
l 成员变量:只能是常量,因为有默认修饰符:public static final
l 构造方法:接口没有构造方法,因为接口主要对行为进行抽象的,是没有具体存在。
一个类如果没有父类,默认继承object类
l 成员方法:只能是抽象方法。默认修饰符:public abstract
关于接口中的方法,jdk8和jdk9中有一些新特性,后面讲解。
13.猫狗接口版本
接口只能调用接口里面的方法,抽象类只能调用抽象类里面的方法。
14. 类和接口的关系
类和类:继承关系,只能单继承,可以多层
类和接口的关系:是实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实 现多个接口。
接口和接口的关系:也是继承关系,可以单继承,也可多继承
15. 抽象类和接口的区别
成员区别:
抽象类:变量、常量;有构造方法、有抽象和非抽象方法
接口;常量、抽象方法
关系区别
关系: |
类与类 |
类与接口 |
接口与接口 |
|
继承、单继承 |
实现(单实现、多实现) |
继承(单继承、多继承) |
设计理念区别 |
抽象类 |
接口 |
|
|
对类抽象(属性行为) |
对行为抽象(主要行为) |
|
强调:抽象类是对事物的抽象、接口是对行为的抽象。
抽象类写事物
接口写行为
分析:从具体到抽象
实现:从抽象到具体
先写什么?先写接口,在写抽象类、再写具体类。最后测试。
抽象类:比如动物,不是具体的事物,涵盖许多具体事物。
抽象类参照多态创建对象,实例化可以说是创建对象,子类可以重写抽象方法
接口:只要拜师就可以学到接口的方法
接口不能直接创建对象,需要用多态形式创建,也就是用它的实现类创建,有父接口指向实现类。
接口中的成员变量都是常量、默认被static final修饰
接口没有构造方法
接口里面的方法只能是抽象的
封装、多态、继承、抽象类、接口