Java提高篇1 - 封装

Java特性 - 封装

  • 隐藏类的属性和内部方法,只暴露必要的访问接口

  • 调整类的属性或者方法时,接口方法不用改动,调整内部实现就可以

  • 可以对成员变量的访问进行控制,(进行逻辑判断检查输入的数据是否符合要求),提高代码健壮性


Java特性 - 继承

1、子类拥有父类==非private==的属性和方法。

2、子类可以拥有自己属性和方法,即子类可以对父类进行扩展。

3、子类可以用自己的方式实现父类的方法。

不支持多继承的原因
==如果多个父类有共同方法,会产生调用不确定性==

this : 代表一个本类对象的引用
super : 代表一个父类空间

子类重写父类方法

注意事项

  • 子类重写父类方法时,子类权限必须要大于等于父类的权限
  • 静态只能覆盖静态,或者被静态覆盖

    应用场景

    对一个类进行子类的扩展时,子类需要保留父类的方法声明,但是要定义子类中该方法的特有内容时,使用重写操作

子类的实例化过程

==子类中所有的构造函数默认都会访问父类中的空参数的构造函数==

子类实例化的时候为什么要访问父类中的构造函数

因为子类继承了父类,获取到了父类中的内容,所有在使用父类内容之前,要先看父类是如何对自己内容进行初始化的,所以子类在构造对象时,必须访问父类中的构造函数

如果父类中没有定义空参构造函数,那么子类==必须在子类构造函数第一行,显式写super语句==,如果使用了this调用本类的构造函数,那么就没有super了,子类中的其他构造函数会访问父类的构造函数

讲到继承一定少不了这三个东西:构造器、protected关键字、向上转型

  • 构造器

通过前面我们知道子类可以继承父类的属性和方法,除了那些private的外还有一样是子类继承不了的—构造器。
对于构造器而言,它只能够被调用,而不能被继承。

==对于继承来说,子类会默认调用父类的构造器,但是如果没有默认的父类构造器,子类必须要显示的指定父类的构造器==,而且必须是在子类构造器中做的第一件事(第一行代码)。

调用父类的构造方法我们使用super()即可。

  • protected关键字
    protected修饰的类,只可以被==子类==以及与它位于==同一个包的类==访问到

  • 向上转型
    将子类转换成父类,在继承关系上面是向上移动的,所以一般称之为向上转型。
    由于向上转型是从一个叫专用类型向较通用类型转换,所以它总是安全的,唯一发生变化的可能就是属性和方法的丢失。

谨慎使用继承

继承存在如下缺陷:
1、父类变,子类就必须变。

2、继承破坏了封装,对于父类而言,它的实现细节对与子类来说都是透明的。

3、继承是一种强耦合关系。

问一问自己是否需要从子类向父类进行向上转型。==如果必须向上转型,则继承是必要的==,但是如果不需要,则应当好好考虑自己是否需要继承。


Java特性 - 多态

多态原理

父类或者接口的引用指向其子类的对象

只有在运行的时候才会知道引用变量所指向的具体实例对象。

多态的好处

  • 提高了代码的扩展性
    原来代码传入一个接口或者类
    扩展时,传入一个子类,原来的代码不用变,==由子类重写原来的方法,原来的引用会指向子类重写后的方法==
    不用重新定义一个方法,传入新的对象

由于继承了父类的子类对象可以==向上转型==为父类对象,所以可以定义==一个父类对象的引用指向子类对象==

指向子类的父类引用由于向上转型了,它只能访问父类中拥有的方法和属性,而==对于子类中存在而父类中不存在的方法,该引用是不能使用的==,尽管是重载该方法。
若==子类重写==了父类中的某些方法,在调用该些方法的时候,必定是使用子类中定义的这些方法(动态连接、动态调用)。

多态时成员的特点

Animal cat = new Cat;

  1. 成员变量
    编译和运行都参考等号的左边
  2. 成员函数(非静态)
    编译看左边,运行看右边
  3. 静态方法
    编译和运行都看左边,==静态方法和类绑定,类名直接调用==

    覆盖重写只发生在方法上,父类的属性无法被覆盖

为了在父类引用中使用子类的特有方法,可以将父类对象==向下转型==,转换成对应的子类引用

判断对象具体类型的关键字

==instanceof==,通常用于向下转型前进行健壮性的判断

多态的三个必要条件

  • 继承、实现:在多态中必须存在有继承关系的子类和父类或者实现类接口的类。
    • 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。
    • 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才能够具备技能调用父类的方法和子类的方法。

多态的实现形式

  • 继承
    对于引用子类的父类类型,在处理该引用时,它适用于继承该父类的所有子类,子类对象的不同,对方法的实现也就不同,执行相同动作产生的行为也就不同。
    ==如果父类是抽象类,那么子类必须要实现父类中所有的抽象方法==,这样该父类所有的子类一定存在统一的对外接口,但其内部的具体实现可以各异。
    这样我们就可以使用顶层类提供的统一接口来处理该层次的方法。
  • 接口
    继承都是单继承,只能为一组相关的类提供一致的服务接口。但是接口可以是多继承多实现,它能够利用一组相关或者不相关的接口进行组合与扩充,能够对外提供一致的服务接口。
    所以它相对于继承来说有更好的灵活性。

根据继承链中方法调用的优先级来确认方法,该优先级为:
this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)。