1. 重载与重写
1.1 重载
(1)发生在一个类中,方法名相同,参数列表不同;
(2)遵循"编译器"绑定,看引用的类型绑定方法;
(3)方法的重载可以看成完全不同的方法,只不过是方法名恰好相同;
遵循:
(1)方法名相同,参数列表(类型和个数)不同;
(2)不能通过访问权限,返回值类型和抛出的异常来实现重载;
(3)可以有不同的访问修饰符、返回值类型、抛出不同的异常;
1.2 重写
(1)发生在父子类中,方法名称相同,参数列表相同,方法体不同;
(2)重写方法被调用时,看对象的类型(遵循"运行期"绑定,看对象的类型绑定方法);
遵循(两同两小一大原则)
两同:方法名相同,参数类型相同;
两小:子类返回类型小于等于父类方法返回类型;
子类抛出异常小于等于父类方法抛出异常;
一同:子类访问权限大于等于父类方法访问权限;
强制类型转换:
子类对象可以声明为父类类型,父类对象不可以声明为子类类型;
在子类对象声明为父类类型后,可以通过强制转型,转型回来;
而父类对象声明为父类类型之后,并不能执行强制类型转化;
因为在子类对象声明为父类类型后,其实对象的真实意义还是子类对象; 参考[类型实例]
1.3 多态
重载(overload)和重写(override)是实现多态的两种主要方式.
实现多态: 接口多态性。 继承多态性。 通过抽象类实现的多态性.
多态的三个条件:
a. 继承的存在(继承是多态的基础,没有继承就没有多态).
b. 子类重写父类的方法(多态下调用子类重写的方法).
c. 父类引用变量指向子类对象(子类到父类的类型转换).
当父类的引用指向子类对象时,通过这个引用能调用什么方法,看引用的类型,而调用的是子类对象里面的方法。
/** * 向上造型:能点出什么来,看引用的类型,调用的方法是对象的 */ public class Test { public static void main(String[] args) { A o = new B(); o.f1(); //B.f1() B b= (B)o; b.f1(); //B.f1() b.f3(); //B.f3() } } class A{ void f1(){ System.out.println("A.f1()"); } } class B extends A{ @Override void f1(){ System.out.println("B.f1()"); } void f3(){ System.out.println("B.f3()"); } }
2. 面向接口编程
为什么要面向接口编程?
减少耦合性,令各个成员依赖于抽象, 而不是依赖于具体,方便维护和扩展[封闭-开放原则].
用法:传递的参数为接口/抽象类
public class Test { public static void main(String[] args) { //面向接口编程 Test.test01(new B()); // B.f1() Test.test01(new C()); // C.f1() } public static void test01(A a) { a.f1(); } } class A{ void f1(){ System.out.println("A.f1()"); } } class B extends A{ @Override void f1(){ System.out.println("B.f1()"); } } class C extends A{ @Override void f1(){ System.out.println("C.f1()"); } }