java中的多态-2

类内多态性
在一个类对象上调用相同名称的方法,但是当参数不同时执行不同的动作
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;
        }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值