- 什么是多态
- 多态中成员变量和方法的调用
- 对象转型
- instanceof
多态是面向对象的三大特征之一。
通俗来讲,多态是同一个行为具有多个不同表现形式或形态的能力。比如同样是动物叫,狗叫和猫叫是不同的。
继承extends和实现implement是多态的前提。代码中体现多态就是父类引用指向子类对象。简单来讲就是我new 一个子类,但是用父类来接受,那么不同的对象都属于父类那个类,但是他们可以有自己的行为和方法。
多态存在的三个必要条件:
- 继承
- 重写
- 父类引用指向子类对象:Parent p = new Child();
例如,都是图形,但是三角形和圆形和正方形画法不一样。
class Shape {
void 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()");
}
}
多态中成员变量和方法的调用
1.当使用多态方式直接访问成员变量时,看接受变量的类是谁,也是就赋值符号左边的类,那就是谁的成员变量。
如下:
父类:
public class Fu {
int age = 30;
public void method() {
System.out.println("父类");
}
子类:
public class Zi extends Fu{
int age = 10;
@Override
public void method () {
System.out.println("子类");
}
}
测试类:
public class Test {
public static void main(String[] args) {
Fu obj = new Zi();
System.out.println(obj.age); // 30
}
}
2.当使用多态方式调用方法时,首先检查父类中是否有该方法,如果没有,则编译错误;如果有,再去调用子类的同名方法。
如下:
父类:
public class Fu {
int age = 30;
public void method() {
System.out.println("父类");
}
public void showAge() {
System.out.println(age);
}
public void methodFu() {
System.out.println("父类特有方法");
}
}
子类:
public class Zi extends Fu{
int age = 10;
String name = "小明";
@Override
public void method () {
System.out.println("子类");
}
@Override
public void showAge() {
System.out.println(age);
}
public void showName() {
System.out.println(age);
}
测试类:
public class Test {
public static void main(String[] args) {
Fu obj = new Zi();
// 以下编译报错,使用不了子类特有方法
// obj.shoeName();
// 调用重写方法,使用的子类方法
obj.method();
// 当方法内使用了成员变量,调了谁的方法,就优先使用谁的属性
obj.showAge(); // 10
// 调用父类方法
obj.methodFu();
}
}
总结:
在多态中,
成员变量使用:编译是否通过看左边,运行也看左边
成员方法使用:编译是否通过看右边,运行看左边,使用不了子类特有方法
1.向上转型
其实就是多态的写法
格式:
父类名 对象名 = new 子类名()
向上转型一定是安全的,从小范围转向了大范围。但是这样就用不了子类特有方法了。
示例:
父类
public abstract class Animal {
public abstract void eat();
}
子类
public class Cat extends Animal{
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void catchMouse() {
System.out.println("猫捉老鼠");
}
}
测试类
public class Test {
public static void main(String[] args) {
Animal animal = new Cat();
animal.eat(); // 猫吃鱼
// animal.catchMouse(); // 编译报错
}
}
2.向下转型
就是将父类对象还原为原本的子类对象
格式:
子类名 对象名 = (子类名称) 父类名
示例:
public class Test {
public static void main(String[] args) {
Animal animal = new Cat();
animal.eat(); // 猫吃鱼
// animal.catchMouse(); // 编译报错
// 向下转型
Cat cat = (Cat)animal;
cat.catchMouse();
}
}
注意:如果转的不是原来的类,会报ClassCastException。
instanceof对象 instanceof 类名,判断对象原来是不是类名的类。
如下:
狗类:
public class Dog extends Animal{
@Override
public void eat() {
System.out.println("狗吃骨头");
}
public void watchHouse() {
System.out.println("狗看家");
}
}
测试类
public class Test {
public static void main(String[] args) {
Animal animal = new Cat();
animal.eat(); // 猫吃鱼
// 使用instanceof判断对象原来所属的类
if (animal instanceof Cat) {
Cat cat = (Cat)animal;
cat.catchMouse();
}
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.watchHouse();
}
}
}



