Day10

作者: 拼搏男孩 | 来源:发表于2019-12-03 07:49 被阅读0次

一. 多态

  1. 定义

    • 一个事物的多种形态
  2. 多态的前提

    • 要有子父关系
    • 要有方法重写
    • 要有父类引用指向子类对象
  3. 演示

    public class Father {
     public void method(){
         System.out.println("父类method方法");
     }
    }
    //子类继承父类
    public class Son extends Father {
         //重写父类的方法
     public void method(){
         System.out.println("子类的method方法");
     }
    }
    public static void main(String[] args) {
     //父类类型的变量引用子类类型的实例对象
     Father father = new Son();
         father.method();
    }
    
  4. 注意事项

    • 可以做哪些工作看父类类型
    • 实际做工作的看子类对象
    • 优点: 提高了代码的扩展性, 复用性, 可以当作形参,用来接收任意类型的子类对象
    • 缺点: 不能使用子类的特有属性和方法
  5. 演示

    • 学校有授课功能, 但是需要聘请老师讲课, 编程模拟
    public class School {
    
     public void teach(Teacher teacher){
         teacher.teach();
     }
    }
    
    public class Teacher {
     public void teach(){
         System.out.println("老师上课");
     }
    }
    
    public class MusicTeacher extends Teacher{
     public void teach() {
         System.out.println("优美的歌声从教室中飘出");
     }
    }
    
    public class MathTeacher extends Teacher{
     public void teach() {
         System.out.println("认真的讲解着每一个运算步骤");
     }
    }
    
    public static void main(String[] args) {
     School school = new School();
     //调用学校的授课功能, 传递一个音乐老师过去
     school.teach(new MusicTeacher());
     //调用学校的授课功能, 传递一个数学老师过去
     school.teach(new MathTeacher());
    }
    

  1. 测试题

    • 动物都有吃饭的功能, 但是小狗吃的是狗粮, 小猫吃的猫粮,当我们将小猫小狗体貌特征遮盖住的时候, 如何判定吃东西的是小猫还是小狗? 编程模拟

二. 多态成员访问的特点

  1. 成员变量

    • 编译看左边(父类) , 运行看左边(父类) (静态绑定)
    • 一般中情况使用极少, 成员变量一般都是私有化的
    public class Father {
     
     String name = "小红";
    }
    public class Son extends Father {
     
     String name = "小明";
     
    }
    public static void main(String[] args) {
     Father father = new Son();
     
     String str = father.name;
     System.out.println(str); //小红
    }
    
  2. 成员方法

    • 编译看左边(父类), 运行看右边(子类), 动态绑定
    • 子类中如果对父类中的方法进行了重写, 父类中的方法无论如何都无法被访问, 这也是java动态绑定的结果
    • 动态绑定会选择最优执行方法, 只要子类重写了父类的方法, 无论在什么地方调用, 都会先找子类
    public class Father {
     
     public void method(){
         System.out.println("父类method方法");
     }
    }
    
    public class Son extends Father {
     
     public void method(){
         System.out.println("子类method方法");
     }
    }
    public static void main(String[] args) {
     Father father = new Son();
     
     father.method();//子类method方法
    }
    
  3. 静态方法

    • 编译看左边(父类),运行看左边(父类)
    public class Father {
     
     public static void method(){
         System.out.println("父类method方法");
     }
    }
    public class Son extends Father {
     
     public static void method(){
         System.out.println("子类method方法");
     }
    }
    public static void main(String[] args) {
     Father father = new Son();
     
     father.method();//父类method方法
     //Father.method();
    }
    
  4. 测试题

    • 判断结果
    package com.qianfeng.duotai;
    class Fu{
     public void show() {
         System.out.println("fu show");
     }
    }
    
    class Zi extends Fu {
     public void show() {
         System.out.println("zi show");
     }
    
     public void method() {
         System.out.println("zi method");
     }
    }
    
    class TestDemo {
     public static void main(String[] args) {
         Fu f = new Zi();
         f.method();
         f.show();
     }
    }
    
    • 判断结果
    class A {
     public void show() {
         show2();
     }
     public void show2() {
         System.out.println("我");
     }
    }
    class B extends A {
     public void show2() {
         System.out.println("爱");
     }
    }
    class C extends B {
     public void show() {
         super.show();
     }
     public void show2() {
         System.out.println("你");
     }
    }
    public static void main(String[] args) {
     A a = new B();
     a.show();
     
     B b = new C();
     b.show();
    }
    

三. 多态转型

  1. 向上转型

    • 将子类对象看作是父类类型, 也就是我们平时使用的多态的形式
    • 这种情况下, 无法调用子类特有的功能
  2. 向下转型

    • 将父类引用指向的子类对象再转回子类类型

    • 这种转型是有危险的, 因为是强制性的, 一旦转向的类型跟这个对象不匹配, 就会报错java.lang.ClassCastException (类型转换异常, 属于运行时异常)

      public static void main(String[] args) {
         Father f = new Son();
         //转回子类类型
         Son son = f; //
      }
      
      

四. final关键字

  1. 定义

    • final 表示最终的, 无法被修改的
  2. final修饰的特点

    • 修饰类, 类不能被继承
    • 修饰变量, 变量就变成了常量, 只能被赋值一次(初始化的时候赋值 )
    • 修饰方法, 方法不能被重写
  3. final 修饰局部变量

    • 基本数据类型 , 是值不能被改变
    • 引用数据类型, 是地址值不能被改变, 对象中的属性可以改变
    • final可以修饰形参
  4. final 修饰成员变量的初始化时机

    • 必须手动赋值

    • 对象初始化完毕之前

    • 类初始化完成前(静态)

      public class Demo {
         
         final String name = "小红";
         {
             //name = "小红";
         }
         public Demo(){
             //name = "小红";
         }
      }
      
      
  5. 测试题

    • 判断结果
    public class Demo {
     
     final String name ="小红";
     
     public void method(){
         name = "小明";
         System.out.println(name);
     }
     //final修饰变量的时候,只能赋一次值
     public void method2(final String name){
         System.out.println(name);
            
         final int age;
         age = 10;
         System.out.println(age);
     }
    }
    
    public static void main(String[] args) {
     Demo demo = new Demo();
     demo.method();
     demo.method2("小红");
    }
    
    

五. 抽象类

  1. 定义

    • 抽象类没有具体的代码实现, 只是规定了方法的基本属性, 然后由子类去实现具体的代码, 抽象类主要是为了定义规则而存在的
  2. 特点

    • 抽象类和抽象方法必须用abstract 关键字修饰
      • abstract class 类名{}
      • abstract 返回追类型 方法名();
    • 抽象类不一定有抽象方法, 有抽象方法的类一定是抽象类或者接口
    • 抽象类不能实例化, 必须由子类继承并重写抽象方法来实例化
    • 抽象类的子类
      • 要么是抽象类
      • 要么重写抽象类中的所有抽象方法(普通类)
  3. 演示

    • 公司的员工必须都要有打卡和工作的功能, 所有员工都是使用指纹打卡, 但是工作的方式因岗位的不同而不同
    public abstract class Employee {
     
     public void sign(){
         System.out.println("指纹打卡");
     }
     
     public abstract void work();
    }
    
    public class Hr extends Employee{
    
     @Override
     public void work() {
         System.out.println("招聘人才"); 
     }
     
    }
    
    public class Coder extends Employee{
    
     @Override
     public void work() {
         System.out.println("努力的敲代码");
     }
    
    }
    
    
  4. 测试题

    • 汽车工厂的已经将车的主体完成,汽车已经可以开动了, 后期需要根据不同的用途安装不同的部件, 货车需要安装货箱, 用来拉货, 客车需要安装座椅,用来拉人
  5. 抽象类成员方法的特点

    • 抽象方法 , 强制要求子类做的事情
    • 非抽象方法, 子类继承的方法, 提高代码的复用性
  6. 优点

    • 强制子类实现父类的方法功能
    • 提高代码的扩展性, 便于后期的维护
    • 形成一套规范(重点)
  7. 测试题

    • 具体事物:猫,狗
    • 共性:姓名,年龄,吃饭 (抽象类中成员变量的使用和普通类是一样的)
    • 猫的特性 : 抓老鼠
    • 狗的特性 : 看家

六. java值传递的三种方式

  1. 基本数据类型值的传递
    • 基本数据类型传递是值, 也就是将具体的值赋给变量名,所以变量名代表的是具体的值
  2. 引用数据类型传递的是地址值
    • 当一个对象赋值给一个对象名, 是将这个对象在内存中的地址值传递给对象名
    • 实例对象在对内存中是有一个16进制的地址值
  3. String 值的传递
    • String 比较特殊, 她虽然是一个引用变量, 但是她传递的是具体的数值
    • String 首先是在对内存中创建一个对象,对象里面封装的是常量值, 然后将数值放入到常量池中, 再指向String
  4. 总结
    • 基本数据类型传递的是值, 引用数据类型传递的是址

七. 接口

  1. 定义

    • 接口其实就是抽象类的升级版, 接口里面都是抽象方法
    • 从狭义上将来说, 接口就是指java 中的interface
    • 从广义上的角度讲对外提供规则的都是接口
    • 接口就是一套标准的规范(规则)
  2. 特点

    • 接口用关键字interface表示
      • interface 接口名{ }
      • 接口中方法上的abstract关键字可以省略
    • 类实现接口用implements表示
      • class类名 implements 接口名{ }
    • 接口不能实例化
      • 接口按照多态的方法实例化
    • 接口的子类
      • 可以是接口,使用extends来继承
      • 可以是抽象类, 但意义不大
      • 可以是实体类, 要重写接口中的所有抽象方法( 主要使用 )
    • 接口中的成员变量必须是静态的 最终 公共, 也就是常量
      • static , final 关键字可以省略 (建议省略)
    • 接口可以继承接口
  3. 演示

    //接口1
    public interface MyInterface {
     //定义了静态常量 static final 可以省略
     static final String NAME = "小红";
     //定义了抽象方法
     public void method();
     //定义了抽象方法
     public void method2();
    }
    //接口2 继承了接口1
    public interface MyInterface2 extends MyInterface {
     //定义了抽象方法
     public void method2();
    }
    //定义实现类实现接口
    public class MyInterfaceSon implements MyInterface2{
     //重写抽象方法
     @Override
     public void method() {
         
         System.out.println("重写method抽象方法");
     }
     //重写抽象方法
     @Override
     public void method2() {
         
         System.out.println("重写method2抽象方法");
     }
    }
    
    
  4. 测试题

    • 定义老师规则接口,定义老师类 讲课方法, 辅导作业方法
    • 定义实现的子类, 不同老师不同的讲课方式和辅导作业的方式

八. 类 , 接口之间的关系

  1. 类与类
    • 继承关系, 只能单继承 ,不能多继承 ,但是可以多层继承
    • 多层继承: 子类继承父类,父类继承祖父类
    • 如果多个父类出现相同的方法,无法区别
  2. 类与接口
    • 实现关系,可以单实现, 也可以多实现, 在继承类的同时,可以多实现
    • 多个接口中出现了名称和参数列表相同的方法, 但是返回值不同, 会报错
  3. 接口与接口
    • 继承关系 ,可以单继承, 也可以多继承
    • 如果多个父类中出现了相同的,子类用谁的都可以

总结:

1. 多态

   * 子类对象可以存到父类的变量中

   * 前提条件
     * 子父类关系
     * 方法重写
     * 父类引用指向子类对象
   * 好处

     * 提高代码的复用性和扩展性
   * 缺点
  • 不能使用子类对象的特有方法

    2. 多态成员访问的特点
    
    • 编译看左边,运行看左边

      • 成员变量
      • 静态方法
    • 编译看左边, 运行看右边 ,只要子类中重写了,一定执行子类的方法

    • 非静态成员方法 (全遮挡)

      1. 多态转型
      • 向上转型 (子类转父类)
  • 线下转型 (父类转子类,有危险), 转之前,要使用 instanceof关键字判断一下

    4. final
    
    • 最终的, 无法被改变 , 只能赋值一次

    • 修饰的特性

      • 修饰类, 类不能被继承
      • 修饰方法, 方法不能被重写
      • 修饰变量, 变量只能赋值一次
    • 修饰成员变量时

      • 在初始化完毕之前必须要赋值
      • 静态是类初始化完毕前
    • 非静态是对象初始化完毕前

      1. 抽象类
      • abstract关键字
      • 制定规则
      • 一个类中如果有抽象方法,这个类也必须是抽象类
      • 抽象类中可以没有抽象方法
      • 抽象不能实例化(创建对象) , 不安全, 抽象方法用不了
      • 抽象类的子类可以是抽象类, 不用重写抽象方法
  • 抽象类的子类可以是非抽象类, 必须重写抽象方法

    6. java传递值得方式
    
  • 基本数据类型传递的是值, 引用数据类型传递的是址, String稍微特殊

    7. 接口
    
    • interface implements

    • 接口中全部都是抽象方法

    • 接口中的成员变量

      • 都是公开的, 静态的, 最终的 public static final
    • 作用

      • 指定规则
      • 思考的过程
    • 代码的框架

    • 我们在思考过程中, 用来记录业务逻辑.

      1. 类和接口之间的关系
      • 类和类: 继承 单继承, 多层继承
      • 类和接口: 实现, 可以多实现
      • 接口和接口: 继承, 可以多继承

作业

  1. 第一题

    • 一档选秀节目, 设计了一个平台供参与者展示才艺, 不同的参与者有不同的才艺. 使用多态编程模拟
  2. 第二题

    • 学生都有学习和做作业的能力 , 但是学习的方式不同, 使用抽象类的方法模拟编程
  3. 第三题

    • 创建一个乐器接口 Instrument, 定义演奏方法play, 定义两个实现类 钢琴 Piano, 小提琴 Violin ,分别实现乐器接口,并做出不同的演奏
  4. 第四题

    • 国家规定, 汽车必须能点火, 能开动, 国家将文件发送到汽车厂商的手中, 厂商生产的汽车必须符合要求, 可以有特性功能, 编程模拟
  5. 扩展题

    class A{
     public String show(D obj){ //D obj = new D();
         return ("A and D"); 
    
     }
     public String show(A obj){ //A obj = new D();
    
         return ("A abd A");
     }
    }
    class B extends A{
     public String show(B obj){
    
         return ("B and B");
     }
     public String show(A obj){
         
         return ("B and A");
     }
    }
    class C extends B{ }
    class D extends B{ }
    
    问题:以下输出结果是什么?
    A a1 = new A();
    A a2 = new B();
    B b = new B();
    C c = new C();
    D d = new D();
    System.out.println(a1.show(b)); ① A abd A
    System.out.println(a1.show(c)); ② A abd A
    System.out.println(a1.show(d)); ③ A and D
    System.out.println(a2.show(b)); ④ B and A
    System.out.println(a2.show(c)); ⑤ B and A
    System.out.println(a2.show(d)); ⑥ A and D
    System.out.println(b.show(b));  ⑦ B and B
    System.out.println(b.show(c));  ⑧ B and B
    System.out.println(b.show(d));  ⑨ A and D
    //能执行哪些方法,看变量的类型
    //如果有多态,那么实际执行那个方法看子类
    //如果有多个方法可行,找最合适的,也就是最接近的
    
    

相关文章

网友评论

      本文标题:Day10

      本文链接:https://www.haomeiwen.com/subject/roiqgctx.html