override->重写(=覆盖)、overload->重载、polymorphism -> 多态
override是重写(覆盖)了一个方法,以实现不同的功能。一般是用于子类在继承父类时,重写(重新实现)父类中的方法。
重写(覆盖)的规则:
1、重写方法的参数列表必须完全与被重写的方法的相同,否则不能称其为重写而是重载.
2、重写方法的访问修饰符一定要大于被重写方法的访问修饰符(public>protected>default>private)。
3、重写的方法的返回值必须和被重写的方法的返回一致;
4、重写的方法所抛出的异常必须和被重写方法的所抛出的异常一致,或者是其子类;
5、被重写的方法不能为private,否则在其子类中只是新定义了一个方法,并没有对其进行重写。
6、静态方法不能被重写,可以被重载。
重写(覆盖)的意义:
举个例子:
咱们上Q的时候,不是可以发图片、字体、语音、等等?
如果让你写这个功能,lz你会怎么写呢?
写一个发图片的方法、写一个发字体的方法、写一个发语音的方法? 这样?
这样写,最起码我觉得有2个很笨的缺点、、
第一,要写的方法多了很多、、
第二,对象在调用方法的时候,要知道调用的是哪个方法、、 是调用发字体、还是发语音、还是发图片等等?
这样不如弄一个父类,在父类中定义一个show()方法。然后子类继承父类。(子类就是指那些发字体的类、发语音的类、发图片的类)
然后各个子类重写父类的show方法、要发字体的就写发字体,发语音的就发语音。。。。。
然后,你就用一个父类的引用指向子类对象,如 :
Father a = new Son();
然后调用它的show方法
a.show();
假设这个 new Son , new 的是发字体的, 那它调用show方法的时候,自然是调用自己的show方法、、也就是发字体的方法
假设这个 new Son, new 的是发图片的,那它调用的就是发图片的方法、、
如此类推
lz 不觉得这样很方便吗? 只写一个show 方法, 不同的对象去调用有不同的效果。
也解决了我上面说的那2个很笨的缺点。
优点:
1、不用写很多方法,只写一个show方法就可以了、
2、对象调用方法的时候只要调用show方法就可以了,虽然调用的是同一个方法,但是却因为不同的对象调用而产生不同的效果、
总结:父类的引用指向子类的对象,调用方法时先去父类中找,没有则报错,有则再到子类中找,如果这个方法在子类中被重写,则执行子类中的方法,否则执行父类中的方法。
overload是重载,一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同。
重载的规则:
1、在使用重载时只能通过相同的方法名、不同的参数形式实现。不同的参数类型可以是不同的参数类型,不同的参数个数,不同的参数顺序(参数类型必须不一样);
2、不能通过访问权限、返回类型、抛出的异常进行重载;
3、方法的异常类型和数目不会对重载造成影响;
多态的概念比较复杂,有多种意义的多态,一个有趣但不严谨的说法是:继承是子类使用父类的方法,而多态则是父类使用子类的方法。
一般,我们使用多态是为了避免在父类里大量重载引起代码臃肿且难于维护。
重载的意义
举个例子:
/*方法的重载,就是一个类中允许同时存在一个以上的同名方法,
*只要这些方法的参数个数或者类型不同即可。
*/
public class OverLoadTest{
public static int add(int a,int b){ //定义一个方法
return a+b;
}
//定义一个与第一个方法相同的名称但参数类型不同的方法
public static double add(double a,double b){
return a+b;
}
public static int add(int a){ //定义与第一个方法参数个数不同的方法
return a;
}
public static int add(int a,double b){ //定义一个成员方法
return 1;
}
//这个方法与前一个方法参数次序不同
public static int add(double a,int b){
return 1;
}
public static void main(String args[]){
System.out.println("调用add(int,int)方法"+add(1,2));
System.out.println("调用add(double,double)方法"+add(2.1,3.3));
System.out.println("调用add(int)方法"+add(1));
}
}
总结:同一个消息可以根据不同的对象做出不同的响应,也是多态的体现。
实例:
[java] view plain copy
print?
public class Shape
{
public static void main(String[] args){
Triangle tri = new Triangle();
System.out.println("Triangle is a type of shape? " + tri.isShape());// 继承
Shape shape = new Triangle();
System.out.println("My shape has " + shape.getSides() + " sides."); // 多态
Rectangle Rec = new Rectangle();
Shape shape2 = Rec;
System.out.println("My shape has " + shape2.getSides(Rec) + " sides."); //重载
}
public boolean isShape(){
return true;
}
public int getSides(){
return 0 ;
}
public int getSides(Triangle tri){ //重载
return 3 ;
}
public int getSides(Rectangle rec){ //重载
return 4 ;
}
}
class Triangle extends Shape
{
public int getSides() { //重写,实现多态
return 3;
}
}
class Rectangle extends Shape
{
public int getSides(int i) { //重载
return i;
}
}
注意Triangle类的方法是重写,而Rectangle类的方法是重载。对两者比较,可以发现多态对重载的优点:
如果用重载,则在父类里要对应每一个子类都重载一个取得边数的方法;
如果用多态,则父类只提供取得边数的接口,至于取得哪个形状的边数,怎样取得,在子类里各自实现(重写)。