面向对象 封装、继承、多态

面向对象 封装、继承、多态

一、封装

1.1 简介

  • 为什么需要封装

    举个例子: 我们使用的电脑,内部有CPU、硬盘、内存条、显卡等部件,部件通过某种连接方式一起工作(电脑从而可以使用)。
    你的需求是使用电脑, 需要关心他内部是怎么调用交互的吗?不需要。
    如果你要调整 cpu 频率, 是不能直接操作硬件的, 而是给你通过了外部接口 BIOS界面, 通过 BIOS 的设置调整,如果频率调高了, 电脑会自动黑屏断电。如果让你直接调整硬件, 频率不经过 BIOS 控制, 高了不就把硬件给烧了吗。

  • 封装的思想

    可以再理解一下上面的电脑例子,电脑中的高内聚和低耦合。
    高内聚: 类的内部数据操作细节自己完成,不允许外部干涉;
    低耦合: 仅对外暴露少量的方法用于使用

  • 仅对外暴露少量的方法用于使用

    通俗的讲,封装就是把该隐藏的隐藏起来,该暴露的暴露出来。那么暴露的程度如何控制呢? 就是依赖访问修饰符。 安全性提高

1.2 访问修饰符

权限修饰符共有4种,分别为 publicprotected缺省private;权限修饰符可以使得数据在一定范围内可见或者隐藏。

修饰符本类本包其他包子类任意位置
private×××
缺省××
protected×
public

权限修饰符可以修饰:

  • 外部类:public和缺省

  • 成员变量、成员方法、构造器、成员内部类:public,protected,缺省,private

1.3 类的封装

  • 类的封装的意义

    隐藏类的实现细节

    • 让使用者只能通过事先预定的方法来访问数据,从而可以在该方法里面加入控制逻辑,限制对成员变量的不合理访问。还可以进行数据检查,从而有利于保证对象信息的完整性。

    • 便于修改,提高代码的可维护性。主要说的是隐藏的部分,在内部修改了,如果其对外可以的访问方式不变的话,外部根本感觉不到它的修改。例如:Java8 -> Java9Stringchar[] 转为 byte[] 内部实现,而对外的方法不变,我们使用者根本感觉不到它内部的修改。

  • 如何进行类的封装?

    • 成员变量(field)私有化
    • 提供标准的 get / set 方法
    public class Person {
         //使用 `private` 修饰成员变量
        private String name;
       	private int age;
     
     	//提供 `getXxx`方法 / `setXxx` 方法,可以访问成员变量
     	public void setName(String n) {
     		name = n;
         }
     
         public String getName() {
             return name;
     	}
     
         public void setAge(int a) {
             age = a;
         }
     
         public int getAge() {
             return age;
         }
         
     }
    

    注意: 通过类的封装之后,我们把 age 私有化了, 用户只能通过调用外部方法 setAge() 设置值 和 getAge() 获取值。如果判断不合法的数据,直接在方法中判断, 不给 age 赋值负数就可以了

二、继承

2.1 简介

  • 生活中的继承

    父辈的东西可以被孩子继承,“子承父业”,“这孩子长得像妈妈”

  • Java中的继承

    Java 中有父类、子类的概念,类似生活中的父子关系,父类中的一些属性和方法可以被子类继承下来使用,不再需要重复定义。

    继承描述的是事物之间的所属关系,这种关系是:is-a 的关系。例如,猫属于动物,狗也属于动物。可见,父类更通用,子类更具体。我们通过继承,可以使多种事物之间形成一种关系体系。

2.2 继承的好处

优点: 提高代码的复用性, 扩展性, 提高开发效率
缺点:增加了类与类之间的耦合度

  • 复用性
    如果要写三个动物类, 每个里面都有动物的名称, 年龄, 每个动物都具有的特征。 使用继承可以复用公共的代码。
  • 扩展性
    每次要新增一个类都需要写相同的代码,不利于扩展。使用继承更加利于扩展了。
  • 缺点:增加了耦合度
    如果我为了复用, 植物也继承了动物类, 这样我植物就有名称和年龄了。看视代码进行了复用。但是如果动物类有改变, 动物可以移动,那么是不是所有的植物类都有问题了。(出现问题的主要原因就是动物和植物增加了耦合导致的)所以要保持 Is -a 的关系

2.3 父类的私有成员可以被继承吗?

子类实际会继承父类的所有成员变量和方法,只是因为是 private 不能访问。
如果子类要访问父类的私有成员, 可以通过父类提供公共的方法来间接访问。

三、多态

3.1 简介

编译时类型与运行时类型不一致,编译时看左边的“父类”,运行时看右边的“子类”。父类引用指向子类对象

  1. 提高程序的 扩展性
  2. 降低类与类之间的耦合度
  • 扩展性
    一个宠物商店要卖小猫, 写一个销售小猫的方法。 如果之后还要卖小狗等等, 是不是需要写好多个方法。 违背了 开闭原则 (面向修改关闭, 面向扩展开放)。使用继承之后直接销售动物,其子类可以直接传递给父类,有再多的动物, 我动物商店卖动物就完了。
  • 降低类与类之间的耦合度
    还是上面的例子, 本身每次有新宠物, 都需要在宠物商店添加。实际上线项目之后,你的类还需要一直改。耦合度太高了,使用父类。有新宠物就有呗。只要你继承动物类,我就能调用你。

3.2 案例

  • 购买动物

    这样每添加一个新宠物, 直接在 market 里面判断返回对应的宠物就可以, 而不是 每添加一个新宠物就必须要新建一个 销售对应宠物的方法

    public class petStore{
    	public Animal market(String type){
    		if("cat".equals(type)){
    			return new Cat();
    		}else if("dog".equals(type)){
    			return new Dog();
    		}
    		return null;
    	}
    }
    
    
  • 喂养动物

    如果要喂养不同的动物, 不使用多态。每有一个新动物。人就要有一个对应的喂养方法, 使用多态 新的动物 直接继承 动物类,重写对应的 eat()方法就可以了, 人类完全不需要改变。

    public class Person{
    	public void feed(Animal animal){
    		animal.eat();
    	}
    }
    

四、向上转型与向下转型

4.1 为什么要类型转换呢?

因为多态,就一定会有把子类对象赋值给父类变量的时候。
但是使用父类变量接收了子类对象之后,我们就 不能调用 子类拥有,而父类没有的方法了。这也是多态给我们带来的一点"小麻烦"。所以,想要调用子类特有的方法,必须做类型转换。

4.2 向上转型与向下转型

向上转型: 自动完成

向下转型:(子类类型)父类变量

4.3 instanceof 关键字

instanceof 关键字 用于判断一个对象的运行时类型

是为了避免 ClassCastException 的发生

	对象 instanceof 数据类型 

对象的运行时类型 <= instanceof 后面数据类型,才为true

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值