多态:
可以理解为事物存在的多种体现形态。
人有什么形态,男人、女人。
多态是子类对象在做着变化。
猫 x = new 猫 ();
动物 x = new 猫();
这就是一个对象具有多种形态。X是猫类型,同时也是“动物”类型。
类型提升 : 把猫提升为动物类型。向上转型
1.多态的体现
父类的引用指向了自己的子类对象
父类的引用也可以接收自己的子类对象
2.多态的前提
必须是类与类之间有关系,要么继承,要么实现
存在覆盖
3.多态的好处
提高了程序的扩展性
4.多态的弊端
提高扩展性,但是只能使用父类的引用访问父类中的成员
静态绑定和动态绑定:
静态绑定:编译时期就可以确定所调用的方法。Java中 只有 final、static、private和构造方法属于静态绑定。
动态绑定:运行时才可以确定所调用的方法。
重载和覆盖:
方法重载:用在用一个类中,所谓的重载是 方法名相同,但是返回值和参数列表可以不同。在程序运行时,编译器会根据传递过来的参数自动选择适合这种参数类型的方法。
方法覆盖:用在继承中。父类的方法在子类中出现,且是一模一样的(包括返回值和参数列表)。
abstract class Animal
{
abstract void eat ();
}
class Cat extends Animal
{
public void eat ()
{
System.out.println("Cat.eat()");
}
}
class Dog extends Animal
{
public void eat()
{
System.out.println("Dog.eat()");
}
}
public class Practice
{
public static void main (String[] args)
{
Cat cat = new Cat();
Dog dog = new Dog();
cat.eat();
dog.eat();
Animal c = new Cat();//类型提升 向上转型
c.eat();
Animal d = new Dog();
d.eat();
}
}
Animal c = new Cat(); c.eat(); c.CatchMoushe();
编译失败:The method CatchMoushe() is undefined for the type Animal
将子类向上转型为父类类型后,该对象所能使用的方法只能是父类拥有的。
而运行时所调用的方法则是子类对象自己的。
如何实现cat的特有方法?
向下转型。
Cat a = (Cat)c;
判断某一类型的引用是否是这个类型 :instanceof
if ( c instanceof Cat )
{
((Cat) c).CatchMoushe();
}
非静态在多态中成员函数的特点:
编译时期:参阅引用型变量所属的类中是否有调用的方法
如果有编译通过,没有则失败
运行时期:参阅对象所属的类中是否有调用的方法
非静态成员函数在多态调用时,编译看左边,运行看右边
就是说:子类中有的,就调用子类的方法,没有的就去父类中找。如果还没有,则是不会编译通过的。
在多态中成员变量的特点:编译运行都参考左边。
class Fu
{
int num = 10;
}
class Zi extends Fu
{
int num = 20;
}
class Main
{
public static void main (String[] args)
{
Fu f = new Zi();
Zi z = new Zi();
System.out.println(f.num+"\n"+z.num);
}
}
输出的结果是:
10
20
静态成员函数的特点:参考左边。
class Fu
{
int num = 10;
static void show ()
{
System.out.println("Fu.show()");
}
}
class Zi extends Fu
{
int num = 20;
static void show ()
{
System.out.println("Zi.show()");
}
}
class Main
{
public static void main (String[] args)
{
Fu f = new Zi();
Zi z = new Zi();
f.show();
z.show();
}
}
输出结果:
Fu.show()
Zi.show()
在别人的文章中看到这么一个例子:
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{}
public class DuoTai {
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)); // ⑨
}
}输出结果:
/* 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 ⑨ */
这个涉及到了方法调用的优先级问题
优先级由高到低依次是:
this.show(O)、
super.show(O)、
this.show((super)O)、
super.show((super)O)。
举个例子说明一下:
①:a1.show(b);
a1是A类的对象,先是 this.show(O) 调用的方法先去A类中找,传递的参数是b类对象,在A中没有该方法,那么按super.show(O)
来找 ,找A的父类,A没有父类,再接着执行this.show((super)O) 找b类的父类,b类的父类是A,在A类中有该方法、输出。
②:a1.show(c)
还是先到A中找方法,A中没有,找A的父类,A没父类,找C的父类,C的父类是B ,A中还是没有方法,再找A的父类中找B,A没父类
再找B的父类,B的父类是A,A中有该方法,输出。
原文地址:http://blog.csdn.net/u013476556/article/details/41723301