面向对象三大特征

面向对象三大特征

(封装、继承、多态)

一、封装

1.1存在的问题

  • 在对象的外部,为对象的属性赋值,可能存在非法数据的录入。
  • 就目前技术,无法对属性的赋值加以控制
  • 使用者对类内部定义的属性直接操作会导致数据的错误、混乱或安全性问题

1.2什么是封装

概念:尽可能隐藏对象的内部实现细节,控制对象的修改及访问的权限。

1.3如何实现封装

  • 将属性使用访问修饰符private进行修饰,被private修饰后,属性仅在本类可见。

  • 提供公共的方法(被public修饰)getXXXsetXXX实现对该属性的操作。

  • 在公共的访问方法内部,添加逻辑判断,进而过滤掉非法数据,以保证数据安全(可选的)

私有化属性 对外提供公共方法(get set)从而隐藏对象内部细节

package com;

public class Person {
    private String name;// 姓名
    private int age;// 年龄
    private String gender;// 性别
    private String id;// 身份证号
    private String tel;// 电话

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    /*
       在公共的访问方法内部,添加逻辑判断,
       进而过滤掉非法数据,以保证数据安全。
    */
    public void setAge(int age) {
        if(age > 0 && age < 130) {
            this.age = age;
        } else {
            this.age = 20;
        }
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        Person person = new Person();
        person.setAge(1000);
        System.out.println(person.getAge());
    }
}

注意:

  • 不可以直接访问属性,仅可访问公共方法;
  • get/set方法是外界访问对象私有属性的唯一通道,方法内部可对数据进行检验和过滤。

1.5JavaBean设计

  • 类:实体类 JavaBean
  • JavaBean分为两种:
    1. 数据承载Bean
    2. 业务逻辑Bean
  • 数据承载Bean
    1. 私有化属性
    2. 对外提供公共的get、set方法
    3. 提供有参无参构造
package com.JavaBean;

public class User {
    private String userName;
    private  String userPassword;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public User() {
    }

    public User(String userName, String userPassword) {
        super();
        this.userName = userName;
        this.userPassword = userPassword;
    }
}

二、继承

2.1什么是继承

2.1.1生活中的继承
  • 生活中的继承是施方一种赠与,受方的一种获得。

  • 将一方所拥有的东西给予另一方。

  • 施方和受方往往二者具有继承关系(直系亲属、亲属)。

2.1.2程序中的继承
  • 程序中的继承,是类与类之间特征(属性)和行为(方法)的一种赠与或获得

  • 两个类之间的继承关系,必须满足is a的关系。

    • Dog is an Animal;

    • Cat is an Animal。

  • 根据上面的关系我们可以设计三个类,Dog、Cat、Animal

    • Dog继承Animal;
    • Cat继承Animal。
  • 被继承的类称为父类,上述案例中的Animal。

  • 继承的类称为子类,上述案例中的Dog和Cat。

2.1.3、父类的选择
  • 现实生活中,很多类别之间都存在着继承关系,都满足is a的关系。

  • 狗是一种动物、狗是一种生物。

  • 多个类别都可作为的父类,需要从中选择出最适合的父类。

//生物
属性:
	品种、年龄、性别
方法:
	呼吸

//动物
属性:
	品种、年龄、性别
方法:
	呼吸、吃、睡
  • 功能越精细,重合点越多,越接近直接父类。
  • 功能越粗略,重合点越少,越接近Object类。

2.1.4父类的抽象

  • 在实际开发中,可根据程序需要使用到的多个具体类,进行共性提取,进而定义父类。
//狗
属性:
	品种、年龄、性别、毛色
方法:
	吃、睡、跑

//鱼
属性:
	品种、年龄、性别
方法:
	吃、睡、游

//鸟
属性:
	品种、年龄、性别、毛色
方法:
	吃、睡、飞

//蛇
属性:
	品种、年龄、性别
方法:
	吃、睡、爬

//动物
属性:
	品种、年龄、性别
方法:
	吃、睡

在一组相同或类似的类中,抽取出共性的特征(属性)和行为(方法),定义在父类中,实现重用。

//父类
public class Animal {
    //公共属性
    String name;
    int age;
    String type;

    //公共方法
    public void sleep(){
        System.out.println("sleep");
    }

    public void eat(){
        System.out.println("eat");
    }
}
//子类
public class Cat extends Animal {

    //独有属性
    String color;

    //独有方法
    public void tmq(){
        System.out.println("吐毛球");
    }
}
//子类
public class Dog extends Animal{
    //独有属性
    String color;

    //独有方法
    public void lookHome(){
        System.out.println("看家");
    }

    public void swim(){
        System.out.println("游泳");
    }
}

package com.jicheng;

public class Test1 {
    public static void main(String[] args) {
        Dog dog = new Dog();

        //使用父类继承的属性
        dog.name="旺财";
        dog.age=5;
        dog.type="阿拉斯加";

        // 使用子类中独有的属性
        dog.color="yello";

        System.out.println("name"+dog.name+"\tage"+dog.age+"\ttype"+dog.type+"\tcolor"+dog.color);

        //使用父类继承的方法
        dog.eat();
        dog.sleep();

        //使用子类独有的方法
        dog.swim();
        dog.lookHome();


        Cat cat = new Cat();
        cat.name="局座";
        cat.color="orange";
        System.out.println(cat.name+cat.color);
        cat.sleep();
        cat.tmq();


    }
}

2.2继承

  • 继承的概念:类与类之间特征和行为的一种赠与或获得

  • 继承的作用:减少代码冗余,提高代码复用

  • 语法:

    class 子类名 extends 父类 { //定义子类时,指定其父类
        //属性
        //构造方法
        //方法
    }
    

    2.3继承的特点

    1. 子类继承父类可以继承父类的属性及方法
    2. 子类也可以拥有自己独立的属性及方法
    3. Java为单继承,一个类只能有一个直接父类,但一个父类可以有多个子类
    4. 多重继承即一个父类还可以继承另一个类,java中最大的object(如果一个没有显示的写出extends 父类 默认继承Object)多级继承,属性和方法逐级叠加。

3.4不可继承

  1. 构造方法不可继承
  2. private 修饰的属性方法不能继承
  3. 父类中使用的默认修饰符的属性和方法在不同包的子类中不能继承

3.5访问修饰符

  • public:公共的
  • private:私有的
  • default:默认的 缺省的 友好的
  • protected:受保护的
本类同包不同类不同包不同类其他
private
default
protected
public

​ ✔:表示可以访问;✘:表示不可以访问;

3.6方法的重写

  • 子类中有父类相同名字的方法称之为方法重写
    • 重写特点:
      • 方法名称、参数列表、返回值类型必须与父类相同
      • 访问修饰符可与父类相同或是比父类更宽泛
    • 作用:
      • 当父类提供的方法无法满足子类需求时
      • @Override建议在重写方法上加 书写 否则会报错
    • 注意:不能被继承的方法也不能被重写
public class Dog extends Animal {
    private String color;//毛色

    //跑
    public void run() {
        System.out.println("run...");
    }

    //子类重写父类中的方法,方法名称、参数列表、返回值类型必须与父类相同。
    @Override
    public void eat() {
        System.out.println("狗吃骨头...");
    }
}
public class Test {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat(); //调用子类中重写的方法。
    }
}

3.7super关键字

  • 含义:直接父类对象

  • 作用:可以调用父类的属性 方法 构造方法

    • 调用父类属性和方法的时候
      1. 当子类和父类有相同名字方法时,this.属性 this.方法名() 调用子类属性和方法
      2. 当子类和父类有相同名字方法时,super.属性 super.方法名() 调用父类中方属性和方法
      3. 如果没有重名属性或者方法,那么this和super都是表示调用父类方法(子类继承而来)
    • 调用父类构造方法时:
      • 注意:创建子类对象前,必须创建父类对象
        1. super()调用的是父类的无参构造,可以省略但是不建议(建议:保留父类无参构造)
        2. super 调用父类有参构造时,要放到构造方法的第一行 super和this不能同时出现
    public class Dog extends Animal {
        private String color;//毛色
    
        //跑
        public void run() {
            System.out.println("run...");
        }
    
        //子类重写父类中的方法,方法名称、参数列表、返回值类型必须与父类相同。
        @Override
        public void eat() {
            super.eat();
            System.out.println("狗吃骨头...");
        }
    }
    
public class A {
    int value = 10;
}

public class B extends A {
    int value = 20; //子类属性遮蔽父类属性

    public void print() {
        int value = 30;

        System.out.println(value); //访问局部变量
        System.out.println(this.value); //访问本类的属性
        System.out.println(super.value); //访问父类的属性
    }
}

public class MyTest2 {
    public static void main(String[] args) {
        B b = new B();
        b.print();//分别输出30、20、10
    }
}

三、多态

3.1什么是多态

  • 概念:多态指的是多种形态,父类引用指向子类对象,从而产生多种形态

在这里插入图片描述

//父类
public class Pet {
    //健康值
    int health;

    public  void toHealth(){
        System.out.println("回复健康");
    }

}
//狗 子类
public class Dog extends Pet{
   @Override
    public void toHealth(){
       System.out.println("啃骨头");
   }
}
//猫 子类
public class Cat extends Pet{
    @Override
    public void toHealth(){
        System.out.println("吃鱼");
    }
}

public class Owner {
/*    public void seedDoctor(Dog dog){
        if (dog.health<80){
            dog.toHealth();
            dog.health=90;
        }
        System.out.println("看完病健康值为:"+dog.health);
    }

    public void seedDoctor(Cat cat){
        if (cat.health<80){
            cat.toHealth();
            cat.health=90;
        }
        System.out.println("看完病健康值为:"+cat.health);
    }*/

    public void seedDoctor(Pet pet){
        if (pet.health<80){
            pet.toHealth();
            pet.health=90;
        }
        System.out.println("看完病健康值为:"+pet.health);
    }

}
public class Test {
    public static void main(String[] args) {
        //创建主人对象
        Owner owner = new Owner();

        //创建宠物子类对象
        Dog dog = new Dog();
        dog.health-=60;
        owner.seedDoctor(dog);

        Pet cat = new Cat();
        cat.health=20;
        owner.seedDoctor(cat);
    }
}

注意:

  • 父类引用仅可调用父类所声明的属性和方法,不可调用子类独有的属性和方法;
  • 子类对象赋值给父类引用,如果运行被重写的方法,实际运行的是子类中的方法。

特点:编译看左边运行看右边

3.2向上转型

  • 子类引用的对象转换为父类类型称为向上转型

  • 程序运行的状态

    • 编译,看左边,左侧是什么类型,就能调用什么样的方法;

    • 运行,看右边,右侧是什么类型,运行时就调用什么样的方法

3.3向下转型

  • 父类引用的对象转换为子类类型称为向下转型

  • 注意:只有转换回子类真实类型,才可调用子类独有的属性和方法。

  • 向下转型时,如果父类引用中的子类对象类型和目标类型不匹配,则会发生类型转换异常(ClassCastException)。

  • 通常向下转型前,应判断引用中的对象真实类型,保证类型转换的正确性。

    • 语法:父类引用 instanceof 类型
 if(a instanceof Dog) {
            Dog d = (Dog)a;
             d.eat();
        } 

3.4多态的两种应用场景

  • 使用父类作为方法形参,实现多态
    • 调用方法是,可传递的实参类型包括:本类型对象+其所有的子类对象
  • 使用父类作为方法返回值,实现多态
    • 调用方法后,可得到的结果类型包括:本类型对象+其所有子类对象

3.5多态的作用

  • 屏蔽子类间的差异
  • 灵活、耦合度低

3.6多态产生条件:

  1. 必须有继承关系(满足 is a)
  2. 必须要有重写
  3. 父类引用指向子类
    型,就能调用什么样的方法;
  • 运行,看右边,右侧是什么类型,运行时就调用什么样的方法

3.3向下转型

  • 父类引用的对象转换为子类类型称为向下转型

  • 注意:只有转换回子类真实类型,才可调用子类独有的属性和方法。

  • 向下转型时,如果父类引用中的子类对象类型和目标类型不匹配,则会发生类型转换异常(ClassCastException)。

  • 通常向下转型前,应判断引用中的对象真实类型,保证类型转换的正确性。

    • 语法:父类引用 instanceof 类型
 if(a instanceof Dog) {
            Dog d = (Dog)a;
             d.eat();
        } 

3.4多态的两种应用场景

  • 使用父类作为方法形参,实现多态
    • 调用方法是,可传递的实参类型包括:本类型对象+其所有的子类对象
  • 使用父类作为方法返回值,实现多态
    • 调用方法后,可得到的结果类型包括:本类型对象+其所有子类对象

3.5多态的作用

  • 屏蔽子类间的差异
  • 灵活、耦合度低

3.6多态产生条件:

  1. 必须有继承关系(满足 is a)
  2. 必须要有重写
  3. 父类引用指向子类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值