多态
该文章的例子来自于
>https://www.runoob.com/java/java-polymorphism.html
面向对象程序设计的三大支柱是封装、继承和多态
继承关系使一个子类能继承父类的特征,并且附加一些新特征。子类是它的父类的特殊化,每个子类的实例都是其父类的实例,凡是反过来不成立。例如:每个圆都是一个几何对象,但是并非每一个几何对象都是圆。因此,总可以将子类的实例传给需要父类型的参数。
使用父类对象的地方都可以使用子类的对象。这就是通常所说的多态(polymorphism,它源于希腊文字,意思是“多种形式”)。简单来说,多态意味着父类型的变量可以引用子类型的对象。
以下是一个 Shape类 Circle Square Triangle 都是它的子类
public class NeedsRun {
public static void main(String[] args) {
show(new Shape());
show(new Circle());
show(new Square());
show(new Triangle());
}
public static void show(Shape s) {
s.draw();
}
}
class Shape {
void draw() {
System.out.println("Shape.draw()");
}
}
class Circle extends Shape {
// void draw() {
// System.out.println("Circle.draw()");
// }
}
class Square extends Shape {
void draw() {
System.out.println("Square.draw()");
}
}
class Triangle extends Shape {
void draw() {
System.out.println("Triangle.draw()");
}
}
当我们调用NeedsRun时,得到的结果是
Shape.draw()
Shape.draw()
Square.draw()
Triangle.draw()
而当我们解除Circle的注释时 我们会得到
Shape.draw()
Circle.draw()
Square.draw()
Triangle.draw()
说明我们在使用多态时,也在使用重写,我们会调用的是子类的方法,当子类没有该方法或者没有重写该方法时,就会自动到他的父类去寻找该方法。
instanceof关键词
a instanceof c 判断a 是不是c 的一个实例 如果是 返回true 否则返回false
public class Test {
public static void main(String[] args) {
show(new Cat()); // 以 Cat 对象调用 show 方法
show(new Dog()); // 以 Dog 对象调用 show 方法
Animal a = new Cat(); // 向上转型
// System.out.println(a instanceof Cat);
a.eat(); // 调用的是 Cat 的 eat
Cat c = (Cat)a; // 向下转型
c.work(); // 调用的是 Cat 的 work
}
public static void show(Animal a) {
a.eat();
// 类型判断
if (a instanceof Cat) { // 猫做的事情
Cat c = (Cat)a;
c.work();
} else if (a instanceof Dog) { // 狗做的事情
Dog c = (Dog)a;
c.work();
}
}
}
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void work() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void work() {
System.out.println("看家");
}
}
显式类型转换
Object A = new Animal();
此时很明显A是Animal类型的实例 但是编译器并不能清楚的认识到 所以当我们
Animal B = A;
编译器将会发生编译错误,这时候需要用到显式的类型转换
Animal B = (Animal)A;
这时才能将A对象引用赋值给B对象
当把一个父类实例转换为它的子类变量(称为向下转换)时,必须使用转换标记"(子类名)"进行显式转换,向编译器表明你的意图
当然 该父类实例 必须同时也是它的子类实例
Java实现多态有三个必要条件:继承、重写、向上转型。
继承:在多态中必须存在有继承关系的子类和父类。
重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。
只有满足了上述三个条件,我们才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而达到执行不同的行为。