• java基础学习_面向对象(下)02_day09总结


    =============================================================================
    =============================================================================
    涉及的知识点有:
      1:final关键字(掌握)
      2:多态(掌握)
      3:抽象类(掌握)
      4:接口(掌握)
    =============================================================================
    =============================================================================
    1:final关键字(掌握)
      (0)由于继承中方法有一个现象:方法重写。
        所以,父类的功能,就会被子类给覆盖掉。
        有些时候,我们不想让子类去覆盖掉父类的功能,只能调用但不能去覆盖修改。
        这个时候,针对这种情况,Java就提供了一个关键字:final。
    ---------------------------------------
      (1)final是最终的意思,常见的final可以修饰类、方法、变量。
      (2)fianl的特点:
        A:final修饰的类,不能被继承。
          编译报错:无法从最终Fu进行继承
          应用:最底层的那个类可以用final修饰,这样该类就不能有儿子了。(即绝育)
        B:final修饰的方法,不能被重写(覆盖/复写)。
          编译报错:Zi中的show()无法覆盖Fu中的show()
        C:final修饰的变量,是一个常量,只能被赋值一次。
          编译报错:无法为最终变量num2分配值

           注意:被final修饰的成员变量没有默认值,必须在构造器(constructor )结束之前被赋予一个明确的值。即在定义被final修饰的成员变量时就给值。 
        小补充:
          常量分为两种:
            1.字面值常量
              例如:"hello"、10、true
            2.自定义常量
              例如:final int x = 10;
    ---------------------------------------
      (3)final关键字面试题相关:
        public、private等权限修饰符会用来修饰成员变量、构造方法和成员方法。
        不会用来修饰局部变量(在方法内部的变量),因为权限修饰符修饰局部变量是没有意义的,在方法内部的局部变量是被封装好的,外界的方法看不到。
        final既可以修饰局部变量也可以修饰成员变量和成员方法。
        A:final修饰局部变量
          a:当局部变量为基本数据类型    值不能发生改变
            final x = 100;
          b:当局部变量为引用数据类型       地址值不能发生改变,但是该对象的堆内存的内容是可以改变的。
            final Student s = new Student();
            s = new Student();   //对象s重新指向了新的地址值,但是对象s被final修饰了,所以这句会报错!
    ---------------------------------------
        B:final修的饰变量的初始化时机
          a:被final修饰的变量只能被初始化一次(默认初始化不算哦)。
          b:被final修饰的变量的初始化时机:在对象构造方法执行完毕前进行赋值就行。
            注意:这个时机仅仅针对的是非静态的常量。因为静态的早早就加载了。
          c:变量常见的给值时机
            1.在定义的时候就给值。(推荐方式)
            2.在构造代码块中给值。
            3.在构造方法中给值。
    -----------------------------------------------------------------------------
    2:多态(掌握)
      (1)某一个事物,在不同时刻表现出来的不同状态。
        猫可以是猫的类型。
          猫 m = new 猫();
        同时猫也是动物的一种,也可以把猫称为动物。
          动物 d = new 猫();
        再举一个例子:水在不同时刻的状态。
    ---------------------------------------
      (2)多态的前提和体现:
        A:多态有继承或者实现关系。
        B:多态有方法重写。(因为多态是靠方法重写来体现不同状态的)
          其实没有方法重写也是可以的,但是如果没有方法重写就没有意义了。
        C:多态有父类或者父接口引用指向子类对象。
          即:父 f = new 子();

        多态的分类:
          a:具体类的多态
            class Fu {}
            class Zi extends Fu {}

            Fu f = new Zi();
          b:抽象类的多态
            abstract class Fu {}
            class Zi extends Fu {}

            Fu f = new Zi();
          c:接口的多态
            interface Fu {}
            class Zi implements Fu {}

            Fu f = new Zi();
    ---------------------------------------
      (3)多态中的成员访问特点:
        A:对于多态中的成员变量的访问
          编译看左边,运行看左边。
          因为子可以访问父的成员变量,父不可以访问子的成员变量。(即:对于成员变量,可以向上访问,不可以向下访问。)
        B:对于多态中的构造方法的访问
          创建子类对象的时候,子类的构造都会默认访问父类构造,为了对父类的数据进行初始化。
        C:对于多态中的成员方法的访问
          编译看左边,运行看右边。
          因为成员方法有重写,父类的成员方法会被子类覆盖掉。因为成员方法是跟对象相关的。
        D:对于多态中的静态方法的访问
          编译看左边,运行看左边。
          因为静态方法只能被静态方法重写,但是静态方法根本算不上重写。因为静态是跟类相关的。所以访问静态方法的时候是左边。

        为什么?
          因为成员方法有方法重写,父类的动作被子类重写掉了,所以该动作走的是儿子的。
          也即对于多态中的成员方法的访问看右边(子类)。
    ---------------------------------------
      (4)多态的好处:
        A:提高了代码的维护性(继承体现)
          因为多态有继承或者实现关系。
        B:提高了代码的扩展性(多态体现)
          原因如下:
          猫狗案例:
            注意几点:
              测试类里面不能放其他东西,只能放创建的对象和通过对象调用的方法。
              把构造方法私有,别人就不能创建对象了,只能通过类名来调用静态方法了。
              针对动物操作的工具类中,调用动物的功能时,形参用动物类进行接收(即多态)。
                即     Animal a = new Cat();
                  a = new Dog();
                  a = new Pig();
                  ......
    ---------------------------------------
      (5)多态的弊端:
        Fu f = new Zi();
        父类不能使用子类的特有功能(即成员方法)。
          因为我们拿父类去访问子类,但是对于成员方法,父类只能访问在父类中定义的方法,在父类中没有定义的方法不能访问。
          简言之:子可以当做父使用,父不能当做子使用。因为子比父的东西要多。

        我父类就想使用子类的特有功能?行不行?
          答:行。
        那怎么行呢?
          法一:创建子类对象调用方法即可。(可以,但是很多时候不合理。而且,重新创建对象,太占内存了。)
            Zi z = new Zi();
          法二:把父类的引用强制赋值给子类的引用。(向下转型)(这样做内存中只有一个对象,省内存!)
            因为引用类型赋值要求类型要兼容!
            Zi z = (Zi)f;
    ---------------------------------------
      (6)多态中的转型问题:
        A:向上转型
          从子到父
          Fu f = new Zi();
        B:向下转型
          从父到子
          Zi z = (Zi)f;   //前提:要求该f必须是能够转换为Zi的。
    ---------------------------------------
      (7)孔子装爹的案例帮助大家理解多态
        //然后就穿上爹的衣服,带上爹的眼睛,粘上爹的胡子。就开始装爹。
        //其实就是向上转型。
        孔子爹 k爹 = new 孔子();

        //脱下爹的装备,换上自己的装备。
        //其实就是向下转型。
        孔子 k = (孔子)k爹;
    ---------------------------------------
      (8)多态的练习
        A:猫狗案例
        B:老师和学生案例
    -----------------------------------------------------------------------------
    3:抽象类(掌握)
      (1)抽象类的概述:
        把多个共性的东西提取到一个类中,这是继承的做法。
        但是呢,这多个共性的东西,在有些时候,方法声明是一样的,但是方法体不一样。
        也就是说,方法声明是一样,但是每个具体的对象在具体实现的时候内容不一样。
        所以,我们在定义这些共性的方法的时候,就不能给出具体的方法体。
        在Java中,一个没有具体的方法体的方法应该定义为抽象方法。
        而在一个类中如果有抽象方法,该类必须定义为抽象类。
    ---------------------------------------
      (2)抽象类的特点:
        A:抽象类和抽象方法必须用关键字abstract修饰。
          格式:
            abstract class 类名 {}
            public abstract void eat();    //没有方法体。
            //public abstract void eat() {}  //有方法体,但方法体为空。会报错。
        B:抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类。
        C:抽象类不能实例化。
          例如:
            abstract class Animal {}
            Animal a = new Animal();   //会报错,因为动物类是抽象的,不能new。
          抽象类有构造方法,但是不能实例化。
          那么抽象类的构造方法的作用是什么呢?
            答:用于子类访问父类数据初始化。
        D:抽象类的子类可能是:
          a:抽象类的子类可以是一个抽象类。这个子类不用重写抽象类中的抽象方法。
          b:抽象类的子类可以是一个具体类(可以new对象,使用多态实例化抽象类)。但这个子类必须重写抽象类中的所有抽象方法。
        E:抽象类的实例化
          通过具体的子类实现的(即:多态的方式。也即:向上转型的方式),其实这也是多态的一种,叫做抽象类多态。
          多态最主要的应用是在抽象类中使用,而不是在具体类中。这样抽象类对外界提供的是抽象的方法,而靠真正具体的子类来重写实现的。
    ---------------------------------------
      (3)抽象类的成员特点:
        A:抽象类的成员变量的特点
          可以有变量
          也可以有常量
        B:抽象类的构造方法的特点
          有构造方法,但是不能实例化。用于子类访问父类数据的初始化。
        C:抽象类的成员方法的特点
          可以有抽象方法       强制具体的子类必须完成某些动作。
          也可以有非抽象方法     使子类继承非抽象方法,提高代码复用性。
    ---------------------------------------
      (4)抽象类的练习:
        A:猫狗案例练习
          示例代码如下:

      1 /*
      2     猫狗案例练习:
      3         具体事物:猫,狗
      4         共性:姓名,年龄,吃饭
      5 ---------------------------------------
      6     分析:从具体到抽象
      7         猫类:
      8             成员变量:姓名,年龄
      9             构造方法:无参,带参
     10             成员方法:吃饭(猫吃鱼)
     11             
     12         狗类:
     13             成员变量:姓名,年龄
     14             构造方法:无参,带参
     15             成员方法:吃饭(狗吃肉)
     16             
     17         因为有共性的内容,所以就提取了一个父类。动物类。
     18         但是又由于吃饭的内容不一样,所以吃饭的方法是抽象的,
     19         而方法是抽象的,则类就必须定义为抽象类。得到抽象动物类。
     20         
     21         抽象动物类:
     22             成员变量:姓名,年龄
     23             构造方法:无参,带参
     24             成员方法:吃饭();
     25 ---------------------------------------    
     26     实现:从抽象到具体
     27         抽象动物类:
     28             成员变量:姓名,年龄
     29             构造方法:无参,带参
     30             成员方法:吃饭();
     31             
     32         具体的狗类:
     33             继承自抽象动物类
     34             重写吃饭();
     35             
     36         具体的猫类:
     37             继承自抽象动物类
     38             重写吃饭();
     39             
     40         测试类:
     41 */
     42 
     43 //定义抽象的动物类
     44 abstract class Animal {
     45     //姓名
     46     private String name;
     47     //年龄
     48     private int age;
     49     
     50     public Animal() {}
     51     
     52     public Animal(String name, int age) {
     53         this.name = name;
     54         this.age = age;
     55     }
     56     
     57     public String getName() {
     58         return name;
     59     }
     60     
     61     public void setName(String name) {
     62         this.name = name;
     63     }
     64     
     65     public int getAge() {
     66         return age;
     67     }
     68     
     69     public void setAge(int age) {
     70         this.age = age;
     71     }
     72     
     73     //定义一个抽象的方法
     74     public abstract void eat();
     75 }
     76 
     77 //定义具体的狗类
     78 class Dog extends Animal {
     79     public Dog() {}
     80     
     81     public Dog(String name, int age) {
     82         super(name, age);
     83     }
     84     
     85     public void eat() {
     86         System.out.println("狗吃肉");
     87     }
     88 }
     89 
     90 //定义具体的猫类
     91 class Cat extends Animal {
     92     public Cat() {}
     93     
     94     public Cat(String name, int age) {
     95         super(name, age);
     96     }
     97     
     98     public void eat() {
     99         System.out.println("猫吃鱼");
    100     }
    101 }
    102 
    103 //测试类
    104 class AbstractTest {
    105     public static void main(String[] args) {
    106         //测试狗类
    107         //具体类测试
    108         //方式1:
    109         Dog d = new Dog();
    110         d.setName("旺财");
    111         d.setAge(3);
    112         System.out.println(d.getName()+"---"+d.getAge());
    113         d.eat();
    114         //方式2:
    115         Dog d2 = new Dog("旺财", 3);
    116         System.out.println(d2.getName()+"---"+d2.getAge());
    117         d2.eat();
    118         System.out.println("---------------------------");
    119         
    120         //多态测试:因为子类中没有定义特有功能,所以可以多态实现。
    121         Animal a = new Dog();
    122         a.setName("旺财");
    123         a.setAge(3);
    124         System.out.println(a.getName()+"---"+a.getAge());
    125         a.eat();
    126         
    127         Animal a2 = new Dog("旺财", 3);
    128         System.out.println(a2.getName()+"---"+a2.getAge());
    129         a2.eat();
    130         System.out.println("---------------------------");
    131         
    132         //练习:测试猫类
    133         //具体类测试
    134         //方式一:
    135         Cat c = new Cat();
    136         c.setName("多啦A梦");
    137         c.setAge(5);
    138         System.out.println(c.getName()+"---"+c.getAge());
    139         c.eat();
    140         //方式二:
    141         Cat c2 = new Cat("哆啦A梦", 5);
    142         System.out.println(c2.getName()+"---"+c2.getAge());
    143         c2.eat();
    144         System.out.println("---------------------------");
    145         
    146         //多态测试:因为子类中没有定义特有功能,所以可以多态实现。
    147         Animal a3 = new Cat();
    148         a3.setName("哆啦A梦");
    149         a3.setAge(5);
    150         System.out.println(a3.getName()+"---"+a3.getAge());
    151         a3.eat();
    152         
    153         Animal a4 = new Cat("哆啦A梦", 5);
    154         System.out.println(a4.getName()+"---"+a4.getAge());
    155         a4.eat();
    156         
    157     }
    158 }

        B:老师案例练习
          示例代码如下:

      1 /*
      2     老师案例练习:
      3         具体事物:基础班老师,就业班老师
      4         共性:姓名,年龄,讲课
      5 ---------------------------------------
      6     分析:    
      7         基础班老师类
      8             姓名,年龄
      9             无参,带参
     10             讲课(讲解JavaSE)
     11         就业班老师类
     12             姓名,年龄
     13             无参,带参
     14             讲课(讲解JavaEE)
     15         抽象老师类
     16             姓名,年龄
     17             无参,带参
     18             讲课();
     19 ---------------------------------------
     20     实现:
     21         抽象老师类
     22         具体的基础班老师类
     23         具体的就业班老师类
     24         测试类
     25 */
     26 
     27 //定义抽象的老师类
     28 abstract class Teacher {
     29     //姓名
     30     private String name;
     31     //年龄
     32     private int age;
     33     
     34     public Teacher() {}
     35     
     36     public Teacher(String name, int age) {
     37         this.name = name;
     38         this.age = age;
     39     }
     40     
     41     public String getName() {
     42         return name;
     43     }
     44     
     45     public void setName(String name) {
     46         this.name = name;
     47     }
     48     
     49     public int getAge() {
     50         return age;
     51     }
     52     
     53     public void setAge(int age) {
     54         this.age = age;
     55     }
     56     
     57     //抽象方法
     58     public abstract void teach();
     59 }
     60 
     61 //具体的基础班老师类
     62 class BasicTeacher extends Teacher {
     63     public BasicTeacher(){}
     64     
     65     public BasicTeacher(String name, int age) {
     66         super(name, age);
     67     }
     68     
     69     public void teach() {
     70         System.out.println("基础班老师讲解JavaSE");
     71     }
     72 }
     73 
     74 //具体的就业班老师类
     75 class WorkTeacher extends Teacher {
     76     public WorkTeacher(){}
     77     
     78     public WorkTeacher(String name, int age) {
     79         super(name, age);
     80     }
     81     
     82     public void teach() {
     83         System.out.println("就业班老师讲解JavaEE");
     84     }
     85 }
     86 
     87 class AbstractTest2 {
     88     public static void main(String[] args) {
     89         //具体的类测试,自己玩
     90         //基础班老师
     91         //方式一:
     92         BasicTeacher bt = new BasicTeacher();
     93         bt.setName("刘意");
     94         bt.setAge(30);
     95         System.out.println(bt.getName()+"---"+bt.getAge());
     96         bt.teach();
     97         //方式二:
     98         bt = new BasicTeacher("刘意", 30);
     99         System.out.println(bt.getName()+"---"+bt.getAge());
    100         bt.teach();
    101         System.out.println("--------------");
    102         
    103         //就业班老师
    104         //方式一:
    105         WorkTeacher wt = new WorkTeacher();
    106         wt.setName("林青霞");
    107         wt.setAge(27);
    108         System.out.println(wt.getName()+"---"+wt.getAge());
    109         wt.teach();
    110         //方式二:
    111         wt = new WorkTeacher("林青霞", 27);
    112         System.out.println(wt.getName()+"---"+wt.getAge());
    113         wt.teach();
    114         System.out.println("---------------");
    115         
    116         //多态测试:因为子类中没有定义特有功能,所以可以多态实现。
    117         //基础班老师
    118         Teacher t = new BasicTeacher();
    119         System.out.println(t);//BasicTeacher@6d06d69c
    120         t.setName("刘意");
    121         t.setAge(30);
    122         System.out.println(t.getName()+"---"+t.getAge());
    123         t.teach();
    124         System.out.println("--------------");
    125         
    126         //对象名没有改哦,因为这是同一个对象此时指向了别的地址。
    127         t = new BasicTeacher("刘意", 30);
    128         System.out.println(t);//BasicTeacher@7852e922
    129         System.out.println(t.getName()+"---"+t.getAge());
    130         t.teach();
    131         System.out.println("--------------");
    132         
    133         //就业班老师
    134         //对象名依旧没有改哦,因为这是同一个对象此时指向了别的地址。
    135         t = new WorkTeacher();
    136         System.out.println(t);//WorkTeacher@4e25154f
    137         t.setName("林青霞");
    138         t.setAge(27);
    139         System.out.println(t.getName()+"---"+t.getAge());
    140         t.teach();
    141         System.out.println("--------------");
    142         
    143         //对象名依旧依旧没有改哦,因为这是同一个对象此时指向了别的地址。
    144         t = new WorkTeacher("林青霞", 27);
    145         System.out.println(t);//WorkTeacher@70dea4e
    146         System.out.println(t.getName()+"---"+t.getAge());
    147         t.teach();
    148     }
    149 }

        C:学生案例练习
          示例代码如下:类同B,不在赘述。
        D:员工案例练习
          示例代码如下:

      1 /*
      2     假如我们在开发一个系统时需要对员工类进行设计,员工包含3个属性:姓名、工号以及工资。
      3     经理也是员工,除了含有员工的属性外,另为还有一个奖金属性。
      4     请使用继承的思想设计出员工类和经理类。要求类中提供必要的方法进行属性访问。
      5 ---------------------------------------    
      6     分析:
      7         普通员工类
      8             成员变量:姓名、工号以及工资。
      9             成员方法:工作
     10         经理类:
     11             成员变量:姓名、工号以及工资,奖金属性。
     12             成员方法:工作
     13 ---------------------------------------            
     14     实现:
     15         抽象员工类
     16         具体的普通员工类
     17         具体的经理类
     18         测试类
     19 */
     20 
     21 //定义抽象员工类
     22 abstract class Employee {
     23     //姓名、工号以及工资
     24     private String name;
     25     private String id;
     26     private int salary;
     27     
     28     public Employee() {}
     29     
     30     public Employee(String name, String id, int salary) {
     31         this.name = name;
     32         this.id = id;
     33         this.salary = salary;
     34     }
     35     
     36     public String getName() {
     37         return name;
     38     }
     39     
     40     public void setName(String name) {
     41         this.name = name;
     42     }
     43     
     44     public String getId() {
     45         return id;
     46     }
     47     
     48     public void setId(String id) {
     49         this.id = id;
     50     }
     51     
     52     public int getSalary() {
     53         return salary;
     54     }
     55     
     56     public void setSalary(int salary) {
     57         this.salary = salary;
     58     }
     59     
     60     //工作
     61     public abstract void work();
     62 }
     63 
     64 //具体的普通员工类
     65 class Programmer extends Employee {
     66     public Programmer() {}
     67     
     68     public Programmer(String name, String id, int salary) {
     69         super(name, id, salary);
     70     }
     71     
     72     public void work() {
     73         System.out.println("按照需求写代码");
     74     }
     75 }
     76 
     77 //具体的经理类
     78 class Manager extends Employee {
     79     //奖金
     80     private int money; //bonus 奖金
     81 
     82     public Manager() {}
     83     
     84     public Manager(String name, String id, int salary, int money) {
     85         super(name, id, salary);
     86         this.money = money;
     87     }
     88     
     89     public void work() {
     90         System.out.println("跟客户谈需求");
     91     }
     92     
     93     public int getMoney() {
     94         return money;
     95     }
     96     
     97     public void setMoney(int money) {
     98         this.money = money;
     99     }
    100 }
    101 
    102 //测试类
    103 class AbstractTest4 {
    104     public static void main(String[] args) {
    105         //测试具体的普通员工类
    106         Employee emp = new Programmer();
    107         emp.setName("林青霞");
    108         emp.setId("czbk001");
    109         emp.setSalary(18000);
    110         System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());
    111         emp.work();
    112         System.out.println("-------------");
    113         emp = new Programmer("林青霞", "czbk001", 18000);
    114         System.out.println(emp.getName()+"---"+emp.getId()+"---"+emp.getSalary());
    115         emp.work();
    116         System.out.println("-------------");
    117         
    118         //测试具体的经理类
    119         /*
    120         emp = new Manager();
    121         emp.setName("刘意");
    122         emp.setId("czbk002");
    123         emp.setSalary(8000);
    124         emp.setMoney(2000);
    125         */
    126         //由于子类经理类有特有的内容-成员变量-奖金,用多态(父类)测试不合适,所以我们用具体的子类来测试。
    127         Manager m = new Manager();
    128         m.setName("刘意");
    129         m.setId("czbk002");
    130         m.setSalary(8000);
    131         m.setMoney(2000);
    132         System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());
    133         m.work();
    134         System.out.println("-------------");
    135         
    136         //通过含参构造方法赋值
    137         m = new Manager("刘意", "czbk002", 8000, 2000);
    138         System.out.println(m.getName()+"---"+m.getId()+"---"+m.getSalary()+"---"+m.getMoney());
    139         m.work();
    140     }
    141 }

    ---------------------------------------
      (5)抽象类的几个小问题
        A:抽象类有构造方法,但是抽象类不能实例化,那么构造方法有什么用?
          答:用于子类访问父类数据的初始化。
        B:一个类如果没有抽象方法,却定义为抽象类,有什么用?
          答:为了不让外界创建该抽象类的对象,要想访问它只能通过该抽象类的子类。
        C:abstract不能和哪些关键字共存?
          a:final         冲突         因为最终方法不能被重写,而抽象的方法需要被具体的子类重写。
            final abstract void show();        //错误: 非法的修饰符组合: abstract和private
          b:private   冲突        因为私有方法不能被继承,所以就不能被重写,而抽象的方法需要被具体的子类重写。
            private abstract void show();   //错误: 非法的修饰符组合: abstract和final
          c:static     无意义    因为抽象方法是没有方法体的,而静态是可以直接通过类名访问的。访问一个没有方法体的方法,意义何在呢?
            static abstract void show();     //错误: 非法的修饰符组合: abstract和static
    -----------------------------------------------------------------------------
    4:接口(掌握)
      (1)回顾猫狗案例,它们仅仅提供一些基本功能。
        部分的猫会钻火圈,狗会跳高等功能,不是动物本身就具备的,
        是在后面的培养中训练出来的,所以,为了体现事物功能的扩展性,
        Java中就提供了接口来定义这些额外功能,并不给出具体实现(说明是抽象方法),将来哪些猫狗需要被培训,只需要这部分猫狗把这些额外功能实现即可。

        其实接口是最最抽象的抽象类。
    ---------------------------------------
      (2)接口的特点:
        A:接口用关键字interface修饰
          interface 接口名 {}
        B:类实现接口用implements修饰
          class 类名 implements 接口名 {}
        C:接口不能实例化
          那么,接口如何实例化呢?
          按照多态的方式来实例化。(即就要去做一个具体的子类,通过具体的子类去实例化)
            由此可见,多态有几种方式:
              1.具体类多态(几乎没有,但是讲解是通过具体类讲解的)
              2.抽象类多态(常用)
              3.接口多态(最常用)
        D:接口的实现类(子类)
          接口的实现类格式:接口名+Impl
          a:接口的实现类是一个抽象类。但是意义不大,因为你是抽象类,最终还得需要具体子类。
            //定义动物培训接口
            interface AnimalTrain {
              public abstract void jump();
            }
            //抽象类实现接口
            abstract class Dog implements AnimalTrain {
            }
          b:接口的实现类是一个具体类,这个类必须重写接口中的所有抽象方法。(推荐方案)
            //定义动物培训接口
            interface AnimalTrain {
              public abstract void jump();
            }
            //具体类实现接口
            class Cat implements AnimalTrain {
              public void jump() {
                System.out.println("猫可以跳高了");
              }
            }
    ---------------------------------------
      (3)接口的成员特点:
        A:接口的成员变量特点:
          只能是常量,并且是静态的。
          因为接口的所有成员变量的默认修饰符都是:public static final
            建议自己手动给出。
        B:接口的构造方法特点:
          接口没有构造方法 。
          那么接口的实现类的无参构造方法默认访问的是谁的无参构造呢?
            答:所有的类都默认继承一个类:Object类。
          因为:类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。
          又因为:类 Object 只有无参构造方法,所以后来要求所有子类都默认调用的是父类的无参构造方法。

            //接口名+Impl这种格式是接口的实现类格式
            /*
            class InterImpl implements Inter {
              public InterImpl() {
                super();
              }
            }
            */
            //上面的写法等价于下面的写法
            class InterImpl extends Object implements Inter {
              public InterImpl() {
                super();
              }
            }
        C:接口的成员方法特点:
          接口的成员方法只能是抽象的。
          因为接口的所有成员方法的默认修饰符都是:public abstract
            建议自己手动给出。
    ---------------------------------------
      (4)类与类、类与接口、接口与接口的关系
        A:类与类的关系
          继承关系,只能单继承,不能多继承(只有一个父类),可以多层继承(可以有爷爷)。
            class Son extends Father {}   //正确
            class Son extends Father, Mother {}   //错误
        B:类与接口的关系
          1.实现关系,可以单实现,也可以多实现。(可以多扩展嘛)
          2.还可以在继承一个类的同时,实现多个接口。(继承类 Object 嘛)
            class Son implements Father, Mother {}   //正确
            class Son extends Object implements Father, Mother {}   //正确
        C:接口与接口的关系
          继承关系,可以单继承,也可以多继承。

        小结:Java中的类是单继承的,Java中的接口可以多继承。
    ---------------------------------------
      (5)抽象类和接口的区别(自己补齐)?
        A:成员区别
          抽象类:
            成员变量:可以有变量,也可以有常量
            构造方法:有(用于子类访问父类数据的初始化)
            成员方法:可以有抽象方法,也可以有非抽象方法
          接口:
            成员变量:只可以是常量
            构造方法:无
            成员方法:只可以是抽象方法
        B:关系区别:
          类与类:
            继承关系,只能单继承和多层继承。
          类与接口:
            实现关系,可以单实现,也可以多实现。
          接口与接口:
            继承关系,可以单继承,也可以多继承。
        C:设计理念不同
          抽象类      被继承体现的是:“is a”的关系,抽象类中定义的是共性功能。
          接口          被实现体现的是:“like a”的关系,接口中定义的是扩展功能。
    ---------------------------------------
      (6)接口练习:

        A:猫狗案例,加入跳高功能
          共有六个类:(这里将接口理解为最最抽象的类)
            跳高接口
            动物类
            猫类
            狗类
            有跳高功能的猫类
            有跳高功能的狗类
            测试类

    示例代码如下:

      1 /*
      2     猫狗案例,加入跳高的额外功能
      3 ---------------------------------------    
      4     分析:从具体到抽象
      5         猫类:
      6             姓名,年龄
      7             吃饭,睡觉
      8         狗类:
      9             姓名,年龄
     10             吃饭,睡觉
     11             
     12         由于有共性功能,所以,我们抽取出一个父类,
     13         抽象动物类:
     14             姓名,年龄
     15             吃饭();
     16             睡觉(){}
     17             
     18         猫类:继承自抽象动物类
     19         狗类:继承自抽象动物类
     20         
     21         跳高的额外功能是一个新的扩展功能,所以我们要定义一个接口。
     22         接口:
     23             跳高
     24             
     25         部分猫类:实现跳高
     26         部分狗类:实现跳高
     27 ---------------------------------------
     28     实现;从抽象到具体
     29      跳高接口
     30      抽象动物类
     31      抽象猫类
     32      抽象狗类
     33      具体的有跳高功能的猫类
     34      具体的有跳高功能的狗类
     35      测试类
     36         
     37     使用:
     38         使用具有跳高功能的具体类进行测试,因为具有跳高功能的具体类具有最多的功能。
     39 */
     40 //定义跳高接口
     41 interface Jumpping {
     42     //跳高功能
     43     public abstract void jump();
     44 }
     45 
     46 //定义抽象动物类
     47 abstract class Animal {
     48     //姓名
     49     private String name;
     50     //年龄
     51     private int age;
     52     
     53     public Animal() {}
     54     
     55     public Animal(String name, int age) {
     56         this.name = name;
     57         this.age = age;
     58     }
     59     
     60     public String getName() {
     61         return name;
     62     }
     63     
     64     public void setName(String name) {
     65         this.name = name;
     66     }
     67     
     68     public int getAge() {
     69         return age;
     70     }
     71     
     72     public void setAge(int age) {
     73         this.age = age;
     74     }
     75     
     76     //吃饭();
     77     public abstract void eat();
     78     
     79     //睡觉(){}
     80     public void sleep() {
     81         System.out.println("睡觉觉了");
     82     }
     83 }
     84 
     85 //具体的猫类
     86 class Cat extends Animal {
     87     public Cat() {}
     88     
     89     public Cat(String name,int age) {
     90         super(name, age);
     91     }
     92     
     93     public void eat() {
     94         System.out.println("猫吃鱼");
     95     }
     96 }
     97 
     98 //具体的狗类
     99 class Dog extends Animal {
    100     public Dog() {}
    101     
    102     public Dog(String name, int age) {
    103         super(name, age);
    104     }
    105     
    106     public void eat() {
    107         System.out.println("狗吃肉");
    108     }
    109 }
    110 
    111 //有跳高功能的具体的猫类
    112 class JumpCat extends Cat implements Jumpping {
    113     public JumpCat() {}
    114     
    115     public JumpCat(String name, int age) {
    116         super(name,age);
    117     }
    118 
    119     public void jump() {
    120         System.out.println("跳高猫");
    121     }
    122 }
    123 
    124 //有跳高功能的具体的狗类
    125 class JumpDog extends Dog implements Jumpping {
    126     public JumpDog() {}
    127     
    128     public JumpDog(String name, int age) {
    129         super(name,age);
    130     }
    131 
    132     public void jump() {
    133         System.out.println("跳高狗");
    134     }
    135 }
    136 
    137 //测试类
    138 class InterfaceTest {
    139     public static void main(String[] args) {
    140         //定义有跳高功能的具体的猫类并测试
    141         //法一:
    142         JumpCat jc = new JumpCat();
    143         jc.setName("哆啦A梦");
    144         jc.setAge(3);
    145         System.out.println(jc.getName()+"---"+jc.getAge());
    146         jc.eat();
    147         jc.sleep();
    148         jc.jump();
    149         
    150         //法二:
    151         JumpCat jc2 = new JumpCat("加菲猫", 2);
    152         System.out.println(jc2.getName()+"---"+jc2.getAge());
    153         jc2.eat();
    154         jc2.sleep();
    155         jc2.jump();
    156         System.out.println("-----------------");
    157         
    158         //定义有跳高功能的具体的狗类并测试
    159         //法一:
    160         JumpDog jd = new JumpDog();
    161         jd.setName("旺财");
    162         jd.setAge(8);
    163         System.out.println(jd.getName()+"---"+jd.getAge());
    164         jd.eat();
    165         jd.sleep();
    166         jd.jump();
    167         
    168         //法二:
    169         jd = new JumpDog("旺财", 8);
    170         System.out.println(jd.getName()+"---"+jd.getAge());
    171         jd.eat();
    172         jd.sleep();
    173         jd.jump();
    174     }
    175 }

        B:老师和学生案例,加入抽烟功能
          共有六个类:(这里将接口理解为最最抽象的类)
            抽烟接口
            人类
            学生类
            老师类
            有抽功能的学生类
            有抽功能的老师类
            测试类

    示例代码同上,不在赘述!

    =============================================================================

  • 相关阅读:
    Java基础06 组合
    纸上谈兵: 树, 二叉树, 二叉搜索树
    Java基础05 实施接口
    纸上谈兵: 队列 (queue)
    纸上谈兵: 数学归纳法, 递归, 栈
    Java基础01 从HelloWorld到面向对象
    纸上谈兵: 表 (list)
    Java基础02 方法与数据成员
    纸上谈兵: 排序算法简介及其C实现
    纸上谈兵: 栈 (stack)
  • 原文地址:https://www.cnblogs.com/chenmingjun/p/8451305.html
Copyright © 2020-2023  润新知