Java关于多态
-
多态
字面意思:对象的多种形态。
Student(子类)<-Person(父类)->Teacher(子类)
Student s=new Student();
学生形态 对象
代表用new创建一个学生对象赋值给Student 类型,代表Student类型(学生对象)现在是学生形态。
有了多态之后,现在可以这样
Person p=new Sstudent();
人的形态 对象
代表用new创建一个学生对象赋值给Person类型,代表Student类型(学生对象)现在是人的形态。
什么是多态?
同类型的对象,表现出不同的形态。所有子类都是父类的不同形态,通俗来就是"类对象"。
多态的表现形式:
父类类型 对象名称=子类对象;
多态的前提:
- 有继承/实现关系(接口)。
- 有父类引用指向子类对象(Fu f=new Zi();)。
- 有方法的重写。(在下面这个图中,Student和Teacher两个类都把show()方法重写了。)
在上面这四个代码中可以知道:如果有个方法的参数是一个类的名字,那么可以向他传入他的子类。
多态的好处:
- 使用父类型作为参数的时候,可以接收所有子类对象,(不能调用子类特有的方法,会报错)
- 体现多态的拓展性与便利。
多态调用成员的特点:
- 变量调用:编译看左边,运行也看左边。
- 方法调用:编译看左边,运行就按右边。
解释:
先写一段代码。
package pdsu_zjh;
import com.sun.crypto.provider.PBES2Core.HmacSHA1AndAES_128;
class Animal{
String name="动物";
public void show () {
System.out.println("Animal -show方法");
}
}
class Dog extends Animal{
String name="狗";
public void show() {
System.out.println("Dog -show方法");
}
}
class Cat extends Animal{
String name="猫";
public void show() {
System.out.println("Cat -show方法");
}
}
public class Test {
public static void main(String []agrs) {
Animal a1=new Dog();//可以理解为动物对象现在是狗形态。
//成员变量:
//编译看左边,运行看左边
//编译看左边,javac编译代码的时候,会看左边的父类有没有这个变量,如果有则编译成功。反之编译失败。
//运行也看左边,java运行代码的时候,实际获取的就是左边父类中的成员变量。
System.out.println(a1.name);//会输出“动物”
//成员方法:
//编译看左边,运行看右边
//编译看左边:java编写代码的时候,会先看左边的父类中有没有这个方法,如果有,编译成功,如果没有则编译失败。
//运行看右边:java运行代码的时候,实际上运行的是子类中的方法,子类可以把方法重写,如果子类没有重写,也就是没有对父类也有并且在这次调用中被调用的方法进行重新写的话,就会默认执行父类中的方法
//也就是如果Dog的show方法被注释掉的话,就会执行父类Animal中的show方法,没被注释掉就执行重写的方法
a1.show();
}
}
变量调用:
理解:Animal a1=new Dog();
这句.使用a1去调用变量和方法,a1是Animal类型的所以默认从Animal这个类中去找,
成员变量:在子类的对象中,会把父类的成员变量继承下来,具体调用哪个是要看这个对象是是谁创建出来的
成员方法:如果子类对方法进行了重写,则会在虚方法表中把父类的方法进行覆盖
多态的优势:
- 在多态形式下,右边对象可以实现解耦合,便于扩展和维护。
Person p=new Student();
p.work();
再说上面这里创造了人这个对象,学生形态,所以工作的方法是学生方法 ,如果想老师工作,就把Student(),改成Teacher();
- 定义一个方法的时候,使用父类型作为参数对象的时候,可以接受所有子类对象,体现多态的扩展性和便利。
多态的劣势:
- 不能调用子类的特有方法,比如说上面的Dog()中再加一个Animal()中没有的方法,就不会调用。因为会先检查左边有没有此方法。
- 解决方法:强转类型。在上面的代码可以 Dog b=(Dog)a;//转换的时候不能转成其他类型,不然会报错,
- 在这里引入一个关键字:instanceof.他能判断一个对象是不是这个类中的
-
if(a1 instanceof Dog){ Dog b1=(Dog)a1;//不能瞎转哦,这里是因为a1是Animal对象的Dog形态。 } else if(.....){...}