何为多态,多态有什么用,多态有什么表现
多态是同一个行为具有多个不同表现形式或形态的能力。
比如说,你喜欢喝酒,你去酒店买酒让服务员给你拿一瓶酒,这个时候服务员问你“要红酒、白酒、洋酒”,这也是多态,下面给出一定代码演示
酒 a=new 洋酒();
酒 a=new 红酒();
酒 a=new 白酒();
从上例就可以看出,酒有不同的形态,有不一样的特性,这就是多态
多态的声明
同样用上面的例子给出解释,例如我有一个类
class 酒{
String color;
}
以及还有几个子类(洋酒、红酒、白酒)派生自酒类,每个都有一个各自的特性变量price
这个时候以下声明是合法的
酒 a=new 白酒();
然后 a.color=“白色”;这样是没问题的,因为你本身就是继承与酒类,可以实现酒的方法以及变量,同时JAVA也是运行父类对象指向子类对象,但是如果你像下面这样就是会报错的
a.price=1000;
很多人就不明白了,明明是new的白酒类,是一个子类对象,为什么还不能用自己的特性方法,这个时候你需要了解一下java的内存加载,首先是编译看左边,如果你父类中不存在这个变量,那么根本通不过编译,就别说后期的运行了。那么,如果你问我需要运行这个变量,应该怎么办,这个时候就需要转型了
向上转型以及向下转型
上转型:是子类对象由父类引用,格式:parent p=new son
下转型:是父类向下强制转换到子类对象(前提是该父类对象必须是经过上转型的对象)
一定注意这里的前提,下转型必须要经过上转型才行,接着用上面的例子举例
现在我们已经经过了上转型:酒 a=new 白酒();
接下来就是下转型:白酒 白=(白酒)a;
然后你现在白.price=1000;就可以运行了
上面的理论就这些了,下面给出两道实际例子
提示:方法以及静态变量是编译看“左边”,运行看“左边”,变量是编译看“左边”,运行看“右边”
public class demo2 {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println(a1.show(b));
System.out.println(a1.show(c));
System.out.println(a1.show(d));
System.out.println(a2.show(b));
System.out.println(a2.show(c));
System.out.println(a2.show(d));
System.out.println(b.show(b));
System.out.println(b.show(c));
System.out.println(b.show(d));
}
}
class A {
public String show(D obj) {
return ("A and D");
}
public String show(A obj) {
return ("A and A");
}
}
class B extends A {
//重载
public String show(B obj) {
return ("B and B");
}
//重写
public String show(A obj) {
return ("B and A");
}
}
class C extends B {
}
class D extends B {
}
输出结果是:
A and A
A and A
A and D
B and A
B and A
A and D
B and B
B and B
A and D
关于上面代码的解释如下:
1.首先我们需要明白,题目最开始我说的原则,以及,题目中有重写方法和重载方法
(1)首先a1就是A的对象,所以直接调用A自身的方法,然后传入的对象b,这个时候因为类A中没有比配的方法,所以将对象b提升成父类a,然后找到比配的方法,输出AA
(2)同(1),一个道理,只是提升多经历了一步
(3)因为传入的本身就是d对象,所以直接有比配的方法,直接打印
(4)这里需要注意前面说的原则了,编译看左边,运行看右边,所以首先去看父类中是否存在这个方法,找到了,这个show(A obj)方法,然而这个方法被B类重写,所以运行B类的show(A obj)打印BA
(5)这里存在一个问题,按道理运行看右边,然后将C对象提升,打印应该是BB,然而结果却是BA,这里我们需要注意,编译是看的左边,如果类A都不存在这个方法,那么编译就直接报错,所以,这个时候一样是在类A里面找,找到了show(A obj)方法,然后被重写,所以打印BA
(6)同(5)一个道理,也是首先在类A里面找到,然后有一个直接比配show(D obj)就可以直接打印AD
(7)(8)就很简单了,本身就是类B的对象,所以直接在类B中寻找,然后找到了,就打印BB
(9)这里需要注意,虽然是类B的对象,但是B是继承的A类,所以A类的方法也可以使用,所以会比配到A类的show(D obj)打印AD
好了,这就是这个题的解释,或许还有其他人的解释和我不一样,
以下我会给出我的总结
1.方法以及静态变量是编译看“左边”,运行看“左边”,变量是编译看“左边”,运行看“右边”
2.有多态,先看父类方法是否存在,或者可以经过提升转换,然后再看子类的重写
3.继承链中对象方法的调用存在一个优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。