一、Override说明

方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

override(重写)

1、方法名、参数、返回值相同。

2、子类方法不能缩小父类方法的访问权限。

3、子类方法不能抛出比父类方法更多的异常(但子类方法可以不抛出异常)。

4、存在于父类和子类之间。

5、方法被定义为final不能被重写。

overload(重载)

1、参数类型、个数、顺序至少有一个不相同。 

2、不能重载只有返回值不同的方法名。

3、存在于父类和子类、同类中。

二、Override使用范例

1,override范例

class Person
{
String name;
int age;
void introduce(void)
{
System.out.println("我的姓名是" + name + ",我的年龄是" + age);
}
}
class Student extends Person
{
String address;
void introduce(void)
{
System.out.println("我是" + name + ",我的年龄是" + age);
System.out.println("我的家在" + address);
}
}
class Test
{
public static void main(String args[])
{
Student s = new Student();
s.name = "张三";
s.age = 18;
s.address = "中国";
s.introduce();
}
}
这样运行结果就是:
我是张三,我的年龄是18
我的家在中国

2,java中override陷阱

//file: MyMain.class
class Base
{
int a=10;
public void show()
{
             System.out.println(a);
}
}
class Ext extends Base
{
int a=200;
public void show(String s)
{
  System.out.println(s);
}
}
public class MyMain
{
public static void main(String[] argv)
{
             Ext obj=new Ext();
             obj.show();
             obj.show("OK");
}
}
请问,执行上面程序,运行是什么?
10
OK

子类要override父类的方法不但名称要相同同时参数表也要相同,不然就是在子类重新写一个方法并不会override父类的方法,同时返回值也必须相同,不然会报错。

举个例子来说,如果您在定义新类别时想要重新定义toString()方法,您可能会写成这样:

CustomObject.java 
public class CustomObject 
{
public String ToString() 
{ 
return "customObject"; 
}
}

在撰写toString()方法时,您因为打字错误或其它的疏忽,将之打成了ToString(),但您编译这个类别时并不会出现任何的错误,编译器只当您是定义了一个新的ToString()。

3,属性的override

属性并非不可以override,成员变量是可以override的,但是成员变量是在编译时解析的(而方法是在运行时解析的),这样一来,当子类要引用父类对象的属性时,实际上它会屏蔽自己的同名属性,只去访问父类对象的属性,所以直接引用变量名和通过方法来获取变量的效果是不一样的,这里有个非常好的例子,有时间好好看看,想想:

class S1 
{
  public String s = "S1";
  public String getS()
 {
    return s;
  }
}
class S2 extends S1
{
  public String s = "S2";
  public String getS() 
{
    return s;
  }
}
 
public class Shadow 
{
  public static void main(String s[]) 
{
    S1 s1 = new S1();
S2 s2 = new S2();
 
    System.out.println(s1.s); // prints S1
    System.out.println(s1.getS()); // prints S1
    System.out.println(s2.s); // prints S2
    System.out.println(s2.getS()); // prints S2
 
    s1 = s2;
    System.out.println(s1.s); // prints S1, not S2 - // since variable is resolved at compile time
    System.out.println(s1.getS()); // prints S2 - // since method is resolved at run time    
  }
}

三、android中Override的使用

在JDK5.0中增加了java.lang.Override的Annotation类型解决override和overload混淆的问题,同时实现了返回值不同也不认为是语法错误,也会执行override。java.lang.Override是个Marker annotation,简单的说就是用于标示,annotation名称本身即包括了要给工具程式的资讯。 java.lang.Override是J2SE 5.0中标准的Annotation型态之一,它对编译器说明某个方法必须是重新定义父类别中的方法,编译器得知这项资讯后,在编译程式时如果发现该方法并非重新定义父类别中的方法,就会回报错误。可以使用java.lang.Override这个Annotation型态,在方法上加上一个@Override的Annotation,告诉编译器您现在定义的这个类别是重新定义父类别中的同名方法,例如:

CustomObject.java 
public class CustomObject 
{
@Override
public String ToString()
{ 
return "customObject";
}
}

 在编译程式时,编译器看到@Override这个Annotation,了解它必须检查这个方法是不是重新定义父类别的ToString()方法,但父类别中并没有这个方法,所以它会回报错误:

CustomObject.java:2: method does not override a method from its superclas
@Override
^
1 error

重新修改一下程式,编译时就不会有问题了:

CustomObject.java 
public class CustomObject 
{
@Override
public String toString()
{
return "customObject"; 
}
}

Android的开发者对@Override肯定是非常熟悉,@Override是伪代码,表示重写(当然不写也可以),不过写上有如下好处:

    1、可以当注释用,方便阅读

    2、编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错比如你如果没写@Override而你下面的方法名又写错了,这时你的编译器是可以通过的(它以为这个方法是你的子类中自己增加的方法)

example:

onCreate时,在方法前面加上@Override系统可以帮你检查方法的正确性。例如:

publicvoidonCreate(BundlesavedInstanceState){…….}
  这种写法是正确的,如果你写成
publicvoidoncreate(BundlesavedInstanceState){…….}
  这样编译器会报如下错误——
Themethodoncreate(Bundle)oftypeHelloWorldmustoverrideorimplementasupertypemethod,
onCreate方法。(因为oncreate应该为onCreate)
@Override,则编译器将不会检测出错误,而是会认为你新定义了一个方法oncreate。