3.3 Java 面向对象特征---封装、继承、多态

面向对象特征—封装、继承、多态

封装:隐藏

继承:提高代码重用性

多态:提高程序扩展性


1)封装 (private protected default public访问权限修饰符)

1、什么是封装?

封装:通常理解为将某个功能封装成了一个方法,例如,写一个工具类,定义了好几个常用的方法。

面向对象中的封装:是隐藏,通过(访问权限修饰符 private protected default public )选择将类中的某些信息对外开放

注意:private String name;//属性私有化, 只是封装的一种体现。

封装什么?

2、为什么要封装?

为了不让外部直接访问,隐藏内部具体属性、方法。

3、怎么封装?

访问权限修饰符 private protected default public 修饰属性、方法

4、外部如何访问封装的 属性、 方法?

①如何访问private 修饰的属性?

setXXX() getXXX() set控制输出的条件 ,get返回值 XXX是属性

package com.feifan.javaoop.Day3;

public class Private {
    
    //如何访问封装的属性
    private  String name;

    //setXXX 为访问私有属性 提供方法
    public void setName(String name) {
        this.name = name;
    }
    // 返回
    public String getName(){
        return  this.name;
    }
}
package com.feifan.javaoop.Day3;

public class PrivateTest {
    public static void main(String[] args) {

        Private p = new Private();
        p.setName("sssssss");  //输出 sssssss
        System.out.println(p.getName());
    }
}

那如何实现输出控制呢?

setXXX方法中加入条件语句 。 XXX表示私有属性

//setXXX 为访问私有属性 提供方法
public void setName(String name) {
    
    //条件语句控制输出   如果对象中的name长度在3~5,输出
    if(name.length()>=3&&name.length()<=5){
        this.name =name;
    }   
}
package com.feifan.javaoop.Day3;

public class PrivateTest {
    public static void main(String[] args) {

        Private p = new Private();
        p.setName("sssssss"); //输出null  因为长度大于5了
        System.out.println(p.getName());
    }
}

②如何访问private修饰的方法?

在什么情况下需要私有化方法?

比如:windows文件窗口可以同时创建多个,但是windows任务管理器窗口只能创建一个。只能创建一个这种情况怎么解决?——使用单例模式

单例模式:一种模板, 解决在一个程序中只能有一个对象的问题。

Java中共23种模板,解决问题

那具体如何实现 单例模式?——对构造方法私有化

因为每创建一个对象,就要写一个构造方法,所以对构造方法私有化后,外部就不能新创建类了

所以通过 getXXX () return ; 向外提供一个方法,用来创建唯一的一个对象,并返回此对象

package com.feifan.javaoop.Day3;

public class WindowDemo {

	static WindowDemo windowDemo;

    private WindowDemo(){
        //将构造方法私有了 ,其他类就不能创建对象了
    }

    //向外提供一个方法,用来创建唯一的一个对象,并返回此对象
    public static WindowDemo getWindowDemo(){ //static 修饰的属性、方法可以通过类名调用

        if(windowDemo == null){
         //没有调用getWindowDemo()时返回为null,调用后输出om.feifan.javaoop.Day3.WindowDemo@1b6d3586  是哈希code值 地址
           windowDemo = new WindowDemo();
        }

        return windowDemo;
    }
}
package com.feifan.javaoop.Day3;

public class TestWindow {
    public static void main(String[] args) {

        System.out.println(WindowDemo.getWindowDemo());
        // 输出om.feifan.javaoop.Day3.WindowDemo@1b6d3586  是哈希code值 地址

    }
}

2)继承 (extends继承 super调用父类构造方法)

总结:
  • 什么是继承? 继承:实现代码重用的一种方式。
  • 继承格式? extends 关键字 A类 extends B类 子类继承父类 、派生类 继承 基类
  • 继承什么? 子类继承父类的所有非私有的属性、方法
  • 什么情况下用? “猫是动物,狗也是动物” 将公有属性方法放到父类
  • 继承特点? 传递性
  • 类没有继承时,默认继承Object基类

1、什么是继承?

是一种设计思想,是实现代码重用程序扩展的一种方式。

代码重用:super.play();

​ super调用父类的play方法,实现代码重用。

程序:方法重写 @Override

父类方法不能满足,子类重写,对程序进行了

在Java中:

  • 用extends 关键字表示继承关系。子类 extends 父类

  • 不支持多继承,一个类只有一个直接父类

  • 继承后 ,子类可以调用父类中的所有非私有的属性、方法

2、什么时候用继承?

比如:

说"猫是动物",“狗也是动物”

  • 符合 is-a 关系的设计,使用继承
  • 将子类共有的属性和行为放到父类中

3、继承特点?

  • 传递性: C extends B, B extends A

    那么C类具有 B类 和A类 的所有非私有的属性和方法。

  • 当一个类没有继承任何类时,JVM默认类继承Object类

    Object类是默认的基类

4、继承中的名词

派生类–子类 父类–基类

派生类 extends 基类

5、继承中的构造方法 (super)

  • 子类构造方法会先调用父类构造方法 。

    创建一个子类,子类要初始化前先要给父类初始化

  • 使用super关键字调用父类任意一个构造方法,必须卸在构造方法第一行

    比如 : 哮天犬 extends 狗 ,狗 extends 动物 ,在test类中,要new 一个哮天犬类,得在哮天犬类中写构造方法,super()必须写在第一行,因为要通过super()调用狗的构造方法,同理,狗中的构造方法第一行要写super()来调用动物的构造方法。

    //构造方法
    public Animal(){
        super();
    }
    
        //构造方法
        public Dog(){
            super();
        }
            //构造方法
            public AngelDog(){
                super();
    
            }
    
  • super 误区:

    super.play(); 通过super调用父类中的play方法,这里 super 指的不是父类对象,而是在创建子类时,把父类中的非私有的属性、方法加载到子类对象中,并不会创建父类。

6、方法重写 (overRide)

1)什么情况下用方法重写?

子类继承父类时,继承过来的方法不能满足自身需求,就可以重写方法。

2)什么是方法重写,方法重写规则是什么?

方法重写就是把父类中的方法框架拿过来,里面的功能按照子类需求重写。

规则:

  • 方法名相同、参数列表相同、返回值类型相同
  • 访问权限不能小于父类权限

注意:

  • 构造方法、静态方法不能重写,成员变量不存在重写

@Override 是java中提供的一种注解标签,放在方法上面,表示方法是从父类重写而来,就会对其语法校验(@Override 在编译期间校验)。

3)方法override(重写) overload(重载) 区别:

方法重写:

父类方法不能满足子类需求,子类重写方法功能。

重写的方法和父类中的方法名、参数、返回值都相同,

重写方法访问权限必须>=父类

方法重载:

方法功能,

方法名相同,但参数(类型、顺序、个数)不同的多个方法

比如:max(int x,int y) 和 max(double x,double y)

7、抽象 类、 抽象方法 (abstract)

  • abstract 修饰的类 、方法

  • 可以没有具体实现,只是定义类、方法,用在顶层设计

  • 一个抽象类里可以没有抽象方法,但一个类里有抽象方法,那它一定是抽象类

  • 抽象方法怎么用? 在设计层面使用(父类),继承关系中使用

    • 子类继承父类,子类继承父类的抽象方法,因为父类没有必要具体实现功能,所以只需要子类对继承的父类抽象方法进行重写(覆盖 override)。

    比如:

    public abstract class Animal {
    
        /*
          		抽象方法
                abstract 修饰的方法是具体方法, 可以没有具体实现
                只是作为一个功能定义,在顶层类中往往需要定义功能,让其他类去实现
                 */
        
         /*
      	代码省略
      	*/
        public abstract void eat();
    }
    
    public abstract class Dog extends Animal {
    
        /*
        抽象类中可以没有抽象方法
         */
        
        /*
      	代码省略
      	*/
    	
        //Dog子类具体实现继承父类的eat方法
        public  void eat() {
            System.out.println("狗吃食物");
        };
    }
    
    
    package com.feifan.javaoop.Day4;
    
    public class AngelDog extends Dog {
    	
       /*
      	代码省略
      	*/
        
        @Override   //对父类继承的eat方法重写
        public void eat() {
    
            super.setName("");
            super.getName();
            System.out.println("哮天犬坐着吃");
        }
    }
    

3)多态 (instanceof)

1、什么是多态?

  • 同一个事物在不同时期不同状态
  • 方法参数在编译期和运行期状态不同
package com.feifan.javaoop.day4.polymorphic;

public class Test1 {
    public static void main(String[] args) {
        Dog dog = new Dog();//Dog的引用指向Dog对象
        Cat cat = new Cat();
        dog.eat();

        /*
           编译期间: 写代码时就是编译期间, Animal dog1在编译期间是Aniaml类型
           运行期间: run运行程序,Animal dog1 在运行期间类型是Dog类型
         */
        /*
           对于成员方法来讲 编译看左边,运行看右边
           对于静态方法,编译和运行都看左边
           对于成员变量,编译和运行都看左边
         */
        Animal dog1 = new Dog();
        dog1.eat();
        dog1.sleep();
        Animal cat1 = new Cat();
        cat1.eat();
        cat1.sleep();
    }
}

2、继承基础上,什么 时候 出现多态? ------喂不同动物,动物吃东西

package com.feifan.javaoop.day4.polymorphic;

public class Test2 {
    public static void main(String[] args) {
        /*
           我们创建一个喂不同的动物,动物吃东西
           先不用多态来实现
         */
        Dog dog=new Dog();
        Cat cat=new Cat();

        Test2 t = new Test2();
        t.feedDog(dog);
        t.feedCat(cat);
    }
    public void feedDog(Dog dog){
        System.out.println("喂狗 ");
        System.out.println("狗吃 ");
        dog.eat();
    }
    public void feedCat(Cat cat){
        System.out.println("喂猫 ");
        System.out.println("猫吃 ");
        cat.eat();
    }
}
package com.feifan.javaoop.day4.polymorphic;

public class Test3 {
    public static void main(String[] args) {
        /*
           我们创建一个喂不同的动物,动物吃东西
            用多态来实现
            把子类类型上升为父类类型  可以用父类类型表示所有的子类对象
         */
        Animal dog=new Dog();
        Animal cat=new Cat();
        Test3 t = new Test3();
        t.feedAnimal(dog);
        t.feedAnimal(cat);

    }
    /*
       多态提高了程序的扩展性  valueOf(Object obj)

       多态存在不足: 使用多态时,不能访问子类中特有的方法, 因为已经向上转为父类类型了,编译期间不能调用子类特有方法
       解决: 需要向下转型
     */
    public void feedAnimal(Animal animal){
        animal.eat();

        //向下类型转换时需要做一个判断
        // animal instanceof Dog 检测animal在运行时 实际的类型是否为Dog ,如果是返回true,否则false
        if(animal instanceof Dog){    // 实例 instanceof
            Dog dog = (Dog)animal;
            dog.play();  //可以访问子类中的特有play方法了
        }

    }
}

3、多态存在条件?

  • 多态存在条件:

    • 继承

    • 重写

    • 父类引用指向子类 Animal Dog = new Dog();

4、提高程序扩展性—向上转型

  • 向上转型: 子类提升为父类

    Animal x=new Cat() //向上转型,Cat对象提升到Animal对象

    x.eat() //只能使用父类中的方法

    x.look() //报错!父类对象不能使用子类中的方法

5、访问子类特有方法— 向下转型

  • 向下转型: 父类对象强制变为子类对象

    Animal x=new Cat()

    Cat m=(Cat)x; //向下转型

    m.eat() ;

    m.look();//子父类中的方法都可以使用

向下转型,时需要加入判断:(instanceoof )实例对象是
//向下类型转换时需要做一个判断
// animal instanceof Dog 检测animal在运行时 实际的类型是否为Dog ,如果是返回true,否则false
if(animal instanceof Dog){    // 实例 instanceof
    Dog dog = (Dog)animal;
    dog.play();  //可以访问子类中的特有play方法了
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宋大米Pro

感谢小主大赏,留言可进互助群~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值