总结动态绑定(多态):动态绑定是指在“执行期间”(而非编译期间)判断所引用的实际对象类型,根据其实际的类型调用其相应的方法。所以实际当中找要调用的方法时是动态的去找的,new的是谁就找谁的方法,这就叫动态绑定。动态绑定帮助我们的程序的可扩展性达到了极致。
多态的存在有三个必要的条件:
- 要有继承(两个类之间存在继承关系,子类继承父类)
- 要有重写(在子类里面重写从父类继承下来的方法)
- 父类引用指向子类对象
public class Text{ //测试类
public static void aaa(Shape s)
{
s.draw();
}
public static void main(String[] args) {
aaa(new Square());
}
}
class Shape //父类
{
public void draw(){}
public void erase(){}
}
class Circle extends Shape //子类
{
@Override
public void draw()
{
System.out.println("im circle draw");
}
@Override
public void erase()
{
System.out.println("im circle erase");
}
}
class Square extends Shape //子类
{
@Override
public void draw()
{
System.out.println("im Square draw");
}
@Override
public void erase()
{
System.out.println("im Square erase");
}
}
解析: 其中Square和Circle子类都覆盖了父类的draw()和erase()方法,测试类的aaa()方法参数要求是Shape类型的参数,而Square和Circle可以被视为Shape,只是能力被弱化而已,类似:Father f=new Son(); f无法调用Son类新定义的方法,只能调用Father类拥有的方法,但是如果Son类重写了Father类的方法,那么调用的是重写后即Son的方法。
缺陷: 如果父类的方法是private修饰时,子类无法覆盖这个方法。
class Text
{
private void aaa()
{
System.out.println("im super method");
}
public static void main(String[] args) {
Text t=new Son();
t.aaa();
}
}
class Son extends Text
{
public void aaa()
{
System.out.println("im son method");
}}
结果:
im super method
解析:private方法被自动认为是final方法,而final方法是不会被覆盖的。 如上例,我们原本想调用子类的aaa()方法,但是这里由于父类的aaa方法是private修饰,此时因为子类的方法无法覆盖那么子类的aaa方法被视为全新的不同于aaa方法的另一种方法(我们可以认为子类的aaa方法被改了方法名)那么当我们在调用aaa方法的时候自然调用的是父类的方法了。 值得注意的是,当private修饰方法时,只有在本类内能够使用调用这个方法,如果将main函数放在Son类里,那么t.aaa()就会报错,因为根本就无法调用这个方法。
静态方法和普通方法的区别:
class Text
{
public static void aaa()
{
System.out.println("im super static method");
}
public void bbb()
{
System.out.println("im super normal method");
}
public static void main(String[] args) {
Text t=new Son();
t.aaa();
t.bbb();
}
}
class Son extends Text
{
public static void aaa()
{
System.out.println("im son static method");
}
public void bbb()
{
System.out.println("im son normal method");
}
}
解析:原意是子类的aaa()和bbb()分别覆盖父类的方法,然后输出子类aaa()和bbb(),但是aaa()是静态方法,与类相关联的,由于t是Text类型的,所以调用的是Text的aaa()方法。