面向对象-多态

JavaSE学习笔记-面向对象之多态

  • 多态是什么?

    • 同样使用的是父类的引用,调用同一个名称的方法,却可以得到不同的调用结果,这就是Java中的多态。
    • 即:同一个函数,多种形态。
    • 实际上多态包括动态多态和静态多态。
    • 使用多态便于灵活的拓展我们开发的程序。
  • 方法覆盖:

    • 在类的继承体系结构中,如果子类中出现了与父类中有同原型的方法,那么认为子类中的方法覆盖了父类中的方法(也称为方法重写)。
    • 通过子类的实例调用被覆盖的方法时,将总是调用子类的方法,而父类的方法将被隐藏。
  • 区分方法覆盖(重写)和方法重载:

    • 方法重写一般在父子类中发生,方法重载一般是同一个类中。
    • 方法重写是方法名一致,形参类型一致,个数一致,返回值类型一致,而且权限修饰符的权限只能大于或等于父类的方法的权限。
    • 可以在方法前面加上@Override检测是否构成重写。
    • 方法重载是方法名一样,形参类型不一样,返回值类型无影响,权限修饰符也无影响。
    • 方法重写出现的前提是必须要有继承关系发生的情况下。
    • 方法重载时,继承不是必须的。
    • 方法重写要求父类和子类中的方法必须是同原型,方法重载各方法的原型是不同的。
  • 例如

    class Person{
        public void run(){
            System.out.println("人跑步!!!");
        }
    }
    
    class Student extends Person{
        public void run(){
            System.out.println("学生跑步!!!");
        }
        public void study(){
            System.out.prinln("学生学习!!!");
        }
    }
    
    class Teacher extends Person{
        public void run(){
            System.out.println("老师跑步!!!");
        }
    }
    
    class TestDemo{
        public static void main(String[] args){
            Person p = new Student();	//引用转型
            p.run();					//调用学生的方法,打印学生跑步!!!
            Person p2 = new Teacher();
            p2.run();					//调用老师的方法,打印老师跑步!!!
            //p 和 p2都是Person类,但是同样调用run方法,打印的结果却是不一样,我们称这样的就是多态
            //只有运行时候才知道运行哪个方法
            //在eclipse中,按住Ctrl键,点p.run();这里会跳转到Person的run方法,而不是运行的那个run方法,这就是动态多态。(继承是前提!!!)
            //由上面的结果可以看出,父类引用指向子类对象,调用方法时,调用的是子类的重写后的方法。
            //p是无法调用student的study方法,那么,我们要怎么调用子类特有的方法呢?
            Student st = (Student)p;	//类比强制类型转换,上面的子类赋值给父类,就相当与自动转换
            st.study();	//打印学生学习!!!
            //注意这里会出现问题,因为如果把p强制转换成Teacher对象的话,会报ClassCastException:造型异常
            //所以建议强制类型转换是,使用instanceOf进行判断
            if(p2 instanceOf Teacher){
                Teacher t = (Teacher)p2;
            }
        }
        
    }
    
    

    由上可以看出:如果不强制转换成子类,那就只能调用父类中定义的方法,如果这个方法被子类覆盖了,那就执行子类中的方法,如果没有,那就调用父类中的方法。

    如果强制转换了,那就可以调用子类中特有的一些方法,如上面的Student的study方法。

  • 静态多态和动态多态:

    • 静态多态:
      • 静态多态也称为编译时多态,即在编译时决定调用哪个方法;
      • 静态多态一般指方法重载;
      • 只要构成了方法重载,就可以认为形成了静态多态的条件,静态多态与是否发生了继承没有必然的联系。
      • 静态多态在eclipse中,按住Ctrl键,点击调用的方法会跳转到运行的方法。
    • 动态多态:
      • 动态多态只有在运行时才知道运行哪个方法。
      • 继承是动态多态的前提!!!
      • 子类要重写方法。
      • 动态多态在eclipse中,按住Ctrl键,点击调用的方法,会跳转到父类的方法,而不是执行的子类中的方法。
  • 抽象类 abstract

    • 使用abstract修饰的类就叫抽象类

    • 如果某个类中包含了抽象方法,那么该类就必须定义为抽象类。

    • 抽象类中可以有成员变量,成员方法,静态变量,静态方法,构造方法,抽象方法可有可无。

    • 抽象类只能用于继承,而且继承的子类要实现父类的所有抽象方法,如果没有实现所有的抽象方法,这个类也为抽象类,只能用于继承,不能直接调用构造方法得到其实例。

    • 抽象方法必须为public或者protected,或者默认包权限(因为如果为private,则不能被子类继承,子类便无法实现该方法),缺省情况下默认为包权限;

    • 定义:

      权限修饰符 abstract class 类名{
      	
          权限修饰符 abstract 返回值类型 抽象方法名;
      }
      

      final和abstract,private和abstract,static和abstract,这些是不能放在一起的修饰符

      解释:因为abstract修饰的方法是必须在其子类中实现(重写),才能以多态方式调用,以上修饰符在修饰方法时期子类都重写不了这个方法,final是不可以重写,private是不能够继承到子类,所以也就不能重写,static是可以重写的,但是由对象的创建方式,static修饰的是优先于对象创建加载进内存,如果static和abstract一起用的话,子类实现了,但是先要创建父类(有父才有子),所以先加载父类,这时子类还没有创建,当然会出问题。

  • 接口 interface

    • 使用interface定义的就是接口,没有class关键字。

    • 如果某个类中的所有方法都是抽象方法,那么可以考虑将该类定义为接口。

    • 接口比抽象类更抽象,相当于定义了一套规范和标准。

    • 接口不能被直接实例化,只能被接口继承(extends)或被类实现(implements)。

    • 接口中只允许有常量和抽象方法。

      • 常量, public static final 常量类型 常量名 = 常量值;
      • public static final 可以省略,编译的时候jvm会自动添加。
      • 抽象方法,所有权限都是public ,不写的话,默认是public ,可以省略abstract关键字。
    • 实现接口时,如果不实现所有的抽象方法,那就要把这个类定义为抽象类。

    • 类实现接口用implements关键字后面加 接口名1,接口名2,接口名3.

    • 定义:

      interface USB{
      	public void test1();
      	void test2();
      	int A = 10;
      	public static final int B = 10;
      }
      
      interface USB2 extends USB{
      	
      }
      
      abstract class Keyboard1 implements USB2{
      	public void test2() {
      		
      	}
      }
      
      class Mouse implements USB2{
      	public void test1() {
      	}
      	public void test2() {
      	}
      	
      }
      
  • 抽象类和接口的区别

    • 抽象类中可以有抽象方法,也可以没有抽象方法(抽象方法用于约束子类的行为),抽象类中可以包含成员属性和普通方法。一个类中如果包含抽象方法,则这个类必须定义为抽象类,一个类继承抽象类,要么实现所有抽象方法,要么也是抽象类。抽象类有构造方法,但是不能被直接实例化,只能用于子类调用,抽象类必须被继承。抽象类的抽象方法不写权限修饰符默认为包权限。
    • 接口中只有常量和抽象方法,不能包含其他的。一个类不能继承多个抽象类,但是可以给同时实现多个接口。借助接口可以实现多继承的效果。接口中的所有东西都是public访问权限。
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值