08_面向对象的三大特性

百知教育 - 孙帅 - 08_面向对象的三大特性

01_封装

  • 概念:
    尽可能 隐藏 对象内部实现细节控制 对象的修改访问权限
  • 访问修饰符:
    private(可将属性修饰为 私有 ,仅本类可见)
  • 公共访问方法:
    • 作用:
      提供公共访问方法,以保证数据的 正常录入
    • 命名规范:
      赋值:setXXX() //使用方法返回值实现赋值
      取值:getXXX() //使用方法返回值实现取值
  • 注意:
    定义类时,应当将类的 属性 设置为 private ,然后 提供公共访问方法

02_继承的概念

  • 继承的实现:

    语法: class 子类 extends 父类{} // 定义子类 时,显示继承父类

  • 继承的特点:

    java为 单继承 ,一个类只能有一个直接父类(因此,类之间才能形成简单的树状结构),但可以多级继承,属性和方法逐级叠加。

  • 代码:
    package day9;
    public class TestInheritance{
    	public static void main(String[] args){
    		Dog dog = new Dog();
    		dog.eat();
    	}
    }
    
    class Animal{
    	public void eat(){
    		System.out.println("eat it");
    	}
    	public void sleep(){}
    }
    
    class Dog extends Animal{
    	public void shout(){}
    }
  • 运行结果:

    在这里插入图片描述

03_访问修饰符

  • 父类的哪些属性和方法能 继承 给子类? <==> 子类能 访问 父类的哪些属性和方法?(难理解

  • 访问修饰符 访问范围 继承性

    private 本类内部 不可继承
    public 公开 可以继承
    (default) 本类+同包 同包子类可以继承
    protected 本类+同包+子类 可以继承

  • 构造方法:

    不可继承

  • 代码:
    package pa;
    public class A{
     private int m1 = 10;
     int m2 = 20;
     protected int m3 = 30;
     public int m4 = 40;
    }
    package pa;
    public class B extends A{
     public void print(){
      System.out.println(m1);
      System.out.println(m2);
      System.out.println(m3);
      System.out.println(m4);
     }
    }
    package pb;
    import pa.A;
    public class C extends A{
     public void print(){
      System.out.println(m1);
      System.out.println(m2);
      System.out.println(m3);
      System.out.println(m4);
     }
    }
  • 运行结果:

    编译B类
    编译C类

04_组合聚合复用原则

  • LSP (面向对象理论中的里氏代换原则)

    内容: 针对父类描述的一句话,将父类换成子类时也必须是成立的。

  • 组合/聚合复用原则

    内容: 对于违反里氏代换原则的两个类,由于不存在is a关系,所以不能定义继承,可以用 组合 的方式实现类的代码 复用

  • (组合/聚合复用原则说明)代码:
    class TechThief{	
    	public void studyTech(){  //10000
    	}
    	public void thief(){}
    }
    
    class YKY{	
    	TechThief techThief = new TechThief();
    	public void studyTech(){
    		techThief.studyTech();
    	}
    }

05_方法覆盖(Override)

  • 概念:
    子类用特殊的 方法实现替换 掉父类继承给它的方法实现。
  • 语法:
    方法名相同,参数表相同,返回值类型相同,访问修饰符相同或 更宽。【private, (default), protected, public(最宽)
  • 注意:
    当父类中的方法为私有时,因为子类没有继承到,所以不叫方法覆盖,也就不遵循方法覆盖的语法要求。

06_对象构造过程

  • 具有继承关系的对象构造过程

    例:(父类)A ---- B ---- C(子类)
    1) 分配空间
    2) 初始化A属性
    3) 调用A构造方法
    4) 初始化B属性
    5) 调用B构造方法
    6) 初始化C属性
    7) 调用C构造方法

  • super
    • 语法: 用在构造方法中,指明 调用父类 哪个 构造方法 ,必须出现在构造方法的 第一行
    • 理解: 如果一个构造方法的第一行不是super(…), 也不是this(…),默认super();
  • 代码:
    package day9;
    public class TestSuper{
     public static void main(String[] args){
      new B();
     }
    }
    class A{
     public A(){
      System.out.println("A()");
     }
     public A(int n){
      System.out.println("A(int)");
     }
    }
    class B extends A{
     public B(){
      super(20);
      System.out.println("B()");
     }
     public B(int n){
      super();
      System.out.println("B(int)");
     }
    }
  • 运行结果:

    在这里插入图片描述

  • 思考:
    class X{	
    	public X(int i){}
    }
    class Y extends X{}
    /*
    编译错误:
    Y类的定义相当于:
    class Y extends X{	
    	public Y(){
    		super();
    	}
    }
    由于X类中没有无参构造方法,所以会编译错误。
    */

07_super引用

  • super.(引用)
    • 含义: 指向 父类 对象
    • 作用: 用于 访问父类 被遮盖的 属性 或者用于 调用父类 被覆盖的 方法
  • 代码:
    package day9;
    public class TestSuper{
     public static void main(String[] args){
      Sup sup = new Sup();
      sup.invoke();
     }
    }
    class Super{
     public void method(){
      System.out.println("Super method");
     } 
    }
    class Sup extends Super{
     public void method(){
      System.out.println("Sup method");
     }
     public void invoke(){
      method();  //Sup method
      super.method();  //Super method
     }
    }
  • 运行结果:

    在这里插入图片描述

08_09_多态的语法

  • 子类对象可以赋值给父类引用
    1. 只能对引用调用其 引用类型 中声明的方法。
      1.1 代码解释:

      package day10;
      public class TestPloymorphism{
       public static void main(String[] args){
        Animal a = new Dog();
        a.eat();
        a.sleep();
        a.shout();
       }
      }
      class Animal{
       public void eat(){
        System.out.println("Animal eat");
       }
       public void sleep(){
        System.out.println("sleep 8 hours");
       }
      }
      class Dog extends Animal{
       public void sleep(){
        System.out.println("sleep 6 hours");
       }
       public void shout(){
        System.out.println("WangWang");
       }
      }
      class Cat extends Animal{
      }

      1.2 运行结果:【编译错误:因为Animal中没有shout()方法】 在这里插入图片描述

    2. 运行时,根据 对象实际类型 ,调用子类覆盖之后的方法。

    3. 对象类型不变强制类型转换,用于父类引用赋值给子类引用,但无法改变对象类型。因此,虽然 编译 能够 通过 ,但是 运行 时会 报错
      3.1 代码解释:

      package day10;
      public class TestPloymorphism{
       public static void main(String[] args){
        Animal a = new Cat();
        a.eat();
        a.sleep();
        //a.shout();  error!
        Dog d = (Dog)a;
        d.shout();
       }
      }
      class Animal{
       public void eat(){
        System.out.println("Animal eat");
       }
       public void sleep(){
        System.out.println("sleep 8 hours");
       }
      }
      class Dog extends Animal{
       public void sleep(){
        System.out.println("sleep 6 hours");
       }
       public void shout(){
        System.out.println("WangWang");
       }
      }
      class Cat extends Animal{
      }

      3.2 运行结果: (编译通过,运行错误:猫的对象类型并没有改变) 在这里插入图片描述

    4. 引用 instanceof 类名<==>“判断引用中的 对象 是不是 类名”, 用作强制类型转换之前进行类型判断,避免类型转换异常
      4.1 代码解释:

      package day10;
      public class TestPloymorphism{
       public static void main(String[] args){
        Animal a = new Dog();
        a.eat();
        a.sleep();
        //a.shout();  error!
        
        if(a instanceof Dog){
         Dog d = (Dog)a;
         d.shout();
        }
       }
      }
      class Animal{
       public void eat(){
        System.out.println("Animal eat");
       }
       public void sleep(){
        System.out.println("sleep 8 hours");
       }
      }
      class Dog extends Animal{
       public void sleep(){
        System.out.println("sleep 6 hours");
       }
       public void shout(){
        System.out.println("WangWang");
       }
      }
      class Cat extends Animal{
      }

      4.2 运行结果:
      在这里插入图片描述

10_多态的意义

  • 多态的作用:

    把不同子类的对象,统一 看作父类对象 来处理,屏蔽 了不同子类的 差异 ,使得代码有更好的 通用性

  • 多态的用法:
    1. 多态用在 参数 m(A a): m方法允许A类或A的某个子类对象作为实参
    2. 多态用在 返回值 A m(): m方法返回的是A类或A的某个子类对象
  • 代码:
    package day10;
    public class TestPloy2{
     public static void main(String[] args){
      /*
      Dog a0 = new Dog();
      Cat a1 = new Cat();
      Monkey a2 = new Monkey();
      Tiger a3 = new Tiger();
      Sheep a4 = new Sheep();
      Cock a5 = new Cock();
      
      a0.eat();
      a1.eat();
      a2.eat();
      a3.eat();
      a4.eat();
      a5.eat();
      */
      
      Animal[] as = {new Dog(), new Cat(), new Monkey(), new Tiger(), new Sheep(), new Cock()};
      for(int i = 0; i < as.length; i++){
       as[i].eat();
      }
      
      Animal a = buyAnimal(2);
      Animal b = buyAnimal(3000);
     }
     /*
     static void feed(Dog d){
      d.eat();
     }
     static void feed(Cat c){
      c.eat();
     }
     ...
     */
     static void feed(Animal a){
      a.eat();
     }
     
     static Animal buyAnimal(int money){
      if(money<5) return new Cock();
      else if(money<50) return new Cat();
      else if(money<200) return new Dog();
      else if(money<500) return new Sheep();
      else if(money<1000) return new Monkey();
      else return new Tiger();
     }
    }
    class Animal{
     public void eat(){}
    }
    class Dog extends Animal{
     public void eat(){
      System.out.println("Dog eats bone");
     }
    }
    class Cat extends Animal{
     public void eat(){
      System.out.println("Cat eats fish");
     }
    }
    class Monkey extends Animal{
     public void eat(){
      System.out.println("Monkey eats banana");
     }
    }
    class Tiger extends Animal{
     public void eat(){
      System.out.println("Tiger eats human");
     }
    }
    class Sheep extends Animal{
     public void eat(){
      System.out.println("Sheep eats grass");
     }
    }
    class Cock extends Animal{
     public void eat(){
      System.out.println("Cock eats rice");
     }
    }
  • 运行结果:

    在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值