public class Test2 { public static void main ( String [] args ) { A2 a = new A2 (); a . pp ( "shitou" ); } } class A2 { public void pp () { System . out . println ( "A2.pp()" ); } public void pp ( Integer k ) { System . out . println ( "A2.pp(int)" ); } public void pp ( Object kk ) { System . out . println ( "A2.pp(String)" ); } public void pp ( int k1 , String k2 ){} public void pp ( String k1 , int k2 ){} }
方法名称相同,参数不同,和返回值类型无关
1.参数个数不同 2.参数类型不同 3.参数顺序不同。注意不同参数名称顺序不同public class Test1 { public static void main ( String [] args ) { Fa ff = new Fa (); ff . pp ( new Integer ( 123 )); // 原则:最佳匹配原则 ff . pp ( 1.234 ); } } class Fa { public void pp () { System . out . println ( "Fa.pp()" ); } public void pp ( Number kk ){ System . out . println ( "Fa.pp(Number)" ); } public void pp ( Integer kk ){ System . err . println ( "Fa.pp(Integer)" ); } }
不确定个数的参数
public class Test1 { public static void main(String[] args) { Fa ff = new Fa(); ff.pp(); //最佳匹配原则 } } class Fa { public void pp() { System.out.println("Fa.pp()"); } public void pp(int... pages) {// 不确定个数的参数 System.out.println("Fa.pp(int...)"); } }
方法的重写和重载
要求:方法的名称一致。
方法的重写 ( 覆盖 ) 要求:方法的名称一致 方法的重写 ( 覆盖 ) 一定发生在父子类之间public class Test4 { public static void main ( String [] args ) { F4 f = new F4 (); f . pp ( 10 ); S4 s = new S4 (); s . pp ( 10 ); F4 fs = new S4 (); fs . pp ( 10 ); } } class F4 { public void pp ( int k ) { System . out . println ( "F4.pp(int)" ); } } class S4 extends F4 { public void pp ( int k ) { // 子类中定义的同名同参数的方法覆盖了父类中的方法定义,如 果需要调用父类中的方法则需要使用 super.pp(k) 进行调用 System . out . println ( "S4.pp(int)" ); } }执行规则: new 谁运行谁的方法,和声明的类型无关 方法的覆盖定义要求方法名称一致
@Override 注解可以使 IDE 工具在编译源代码时进行检查,如果有手写错误则 IDE 工具报错
方法的参数一致(个数、类型、顺序),和参数名称无关
类型一致的问题 class Fa { public void eat ( Integer kk ) { System . out . println ( "Animal.eat()" ); } } class Son extends Fa { @Override public void eat ( Number kk ) { // 类型必须一致,即使父类类型都不可以, int 和 Integer 简单类型和包装类型也不可以。这里去除 @override 注解则不会有语法错误,这里不是方法的重写,是方法的重载 System . out . println ( " 就是爱老鼠 " ); } }顺序一致的问题 , 系统识别方法依靠是方法名称和参数类型列表,和方法参数的名称无关。例如这里系统识别的方法为ear(String,String) 。要识别顺序还得依靠类型的区别,例如 eat(int,double) 和 eat(double,int)
class Fa { public void eat ( String s1 , String s2 ) { System . out . println ( "Animal.eat()" ); } } class Son extends Fa { @Override public void eat ( String s2 , String s1 ) { // 系统不能识别变量名称 System . out . println ( " 就是爱老鼠 " ); } }返回数据类型一致【面试】 ( 因为如果返回类型不一致,则无法进行语法检查 , 例如父类返回 Double ,而子类返回 Integer, 调用处语法检查是按照 Double 进行检查还是按 Integer 检查?允许父 类中返回的是父类型,而子类中返回子类型,例如父类中返回的是 Number 类型,而子类中返回的 是 Integer)
class Fa { public Number eat ( double s1 , int s2 ) { System . out . println ( "Animal.eat()" ); return 10. ; } } class Son extends Fa { @Override public Integer eat ( double s2 , int s1 ) { // 允许子类中返回值类型是父类返回值 类型的子类型 System . out . println ( " 就是爱老鼠 " ); return 99 ; } }
抛出异常一致,注意实际上允许子类抛出比父类更少的异常
class Fa { public Integer eat(double s1, int s2) throws Exception { System.out.println("Animal.eat()"); return 10; } } class Son extends Fa { @Override public Integer eat(double s2, int s1) throws IOException { System.out.println("就是爱老鼠"); return 99; } }要求子类中的方法范围 >= 父类中方法范围 静态方法覆盖和调用,用谁声明则调用谁的静态方法
只有静态方法覆盖定义父类中的静态,实际上系统不建议这种做法
//The method pp() of type Son must override or implement a supertype method public class Test1 { public static void main ( String [] args ) { // 直接使用具体类调用静态方法没有任何问题,使用哪个类就调用的是哪个类中定义 的静态方法 // Fa.pp();Fa...pp // Son.pp();Son...pp // 事实上静态方法也可以通过创建对象后,使用对象进行调用。声明变量的类型和具 体构建的类型一致,也不会有问题 // Fa ff=new Fa(); // ff.pp(); // 如果调用静态方法,则用谁声明调用谁的方法 Fa ff = new Son (); ff . pp (); // 执行结果是 Fa...pp } } class Fa { public static void pp () { System . out . println ( "Fa...pp" ); } } class Son extends Fa { public static void pp () { System . out . println ( "Son...pp" ); } }
方法的重载
方法的名称相同,参数不同,和返回值类型无关。可以在一个类内或者父子类之间 调用规则:类型最佳匹配原则class A5 { public void pp (){ System . out . println ( "A5.pp()" ); } public int pp (){} 语法错误,因为在系统中识别一个方法是用【方法名称 + 参数类型列表】进行,系统会将这两个pp 方法识别为同一个方法。注意:在一个类中不允许方法相同 public void pp ( int k ){ System . out . println ( "A5.pp(int)" ); } } class B5 extends A5 { public void pp ( String k ){ System . out . println ( "B5.pp(String)" ); } public void pp ( String k , int k1 ){} public void pp ( int k , String k1 ){} }
多态的优点
1.消除类型之间的耦合关系 2.可替换性、可扩充性 3.接口性、灵活性、简化性public class Test1 { public static void main(String[] args) { Fa ff = new Son(); ff.pp(10);//因为在父类中声明的方法为Integer 类型,所以在执行前会自动执行装箱操作,所以调用的是从父类中继承到的pp(Integer) ,而不是最佳匹配的 pp(int) } } class Fa { protected void pp() { System.out.println("Fa.pp()"); } public void pp(Integer kk){ System.out.println("Fa.pp(Integer)"); } } class Son extends Fa { public int pp(int k) { System.out.println("Son.pp(int)"); return 10; } }
public class Test1 { public static void main(String[] args) { Fa ff = new Son(); ff.pp(10); } } class Fa { protected void pp() { System.out.println("Fa.pp()"); } public void pp(Integer kk){ System.out.println("Fa.pp(Integer)"); } } class Son extends Fa { public void pp(Integer kk){ System.out.println("Son.pp(Integer)"); } public int pp(int k) { System.out.println("Son.pp(int)"); return 10; } }



