核心
多态性是OOP中的一个重要特性,主要是用来实现动态联编的,换句话说,就是程序的最终状态只有在执行过程中才被决定而非在编译期间就决定了。这对于大型系统来说能提高系统的灵活性和扩展性。
引用变量的两种类型
编译时类型
由声明时的类型决定。(模糊一点,一般是一个父类)
运行时类型
由实际对应的对象类型决定。(运行时,具体是哪个子类就是哪个子类)
多态存在的三个必要条件
继承(继承类;继承抽象类;实现接口)
重写
父类引用指向子类空间
继承
定义
子类继承父类的所有属性和行为,使得子类具备父类的各种属性和方法。
格式
继承用extends关键字来实现
class 子类 extends 父类 { }
优缺点
优点:提高代码的复用性 ; 提高了代码的维护性 ; 建立了类与类之间的关系。
缺点:照成类与类之间的强关联,高耦合 ; 父类功能的改变对子类也会照成影响。
注意
构造方法不能继承。
单继承,一个子类只能继承一个父类。
可以多重继承,例如:
public class A{…}
public class B extends A{…}
public class C extends A{…}
重写
返回类型必须与重写方法的返回类型相同。例如:父类A: void eat(){} 子类:int eat(){} 参数类型相同,返回类型不同,不是重写 : 父类A : int eat(){} 子类B : long eat(){} 返回类型兼容父类,但是不相同就不是重写。
参数列表必须与重写方法的参数列表相同。 如果子类的参数与父类对应的方法参数不同,那是重载不是重写。重载的方法名相同,参数列表不同。
子类重写后的访问修饰符权限必须大于父类。
引用数据类型的类型转换
子类转换为父类
自动转换
上转型对象不能操作子类新增的成员变量和方法
上转型对象可以操作子类继承或重写的成员变量和方法。
如果子类重写了父类的某个方法,上转型对象调用该方法时,是调用的重写方法。
父类转换为子类
强制转换
因为子类拥有比父类更多的属性和方法,所以父类在转换为子类时需要强制转换。
多态示范代码
class Animal {
int age=10;
public void shout(){
System.out.println("叫了一声!");
}
}
class Dog extends Animal {
int age=28;
public void shout() {
System.out.println("旺旺旺!");
}
public void gnawBone(){
System.out.println(“我在啃骨头");
}
}
class Cat extends Animal {
int age=18;
public void shout() {
System.out.println("喵喵喵喵!");
}
}
public class TestPolym {
public static void main(String[] args) {
Animal animal = new Dog(); //向上可以自动转型
System.out.println(animal.age); //属性调用时,仍然是基类的属 性。属性没有多态!
// animal.shout();
animalCry(new Dog());
//传的具体是哪一个类就调用哪一个类的方法。大大提高了程序的可扩展性。
//如果没有多态,我们这里需要写很多重载的方法。如果增加一种动物,就需 要重载一种动物的喊叫方法。非常麻烦。
//有了多态,只需要增加这个类继承Animal基类就可以了。
animalCry(new Cat());
Dog dog = (Dog) animal; //编写程序时,如果想调用运行时类型的方 法,只能进行类型转换。不然通不过编译器的检查。
dog.gnawBone();
System.out.println(dog instanceof Animal);
System.out.println(animal instanceof Cat);
System.out.println(animal instanceof Dog);
}
static void animalCry(Animal a){
a.shout();
}
}