每个学习Java的人,都能很直接的说出来Java的三大特性:封装,继承,多态。

<封装>

封装是把过程和数据包围起来,对数据的访问只能通过自定义的接口,这个可以保护里面的数据和结构不被修改。也就是建立一个私有对象,并把某些操作暴露给外部,这样可以让外部调用我们的方法来实现某些功能,但是某些具体的操作是不可见的


对于封装而言,一个对象它所封装的是自己的属性和方法,所以它是不需要依赖其他对象就可以完成自己的操作。

       使用封装有三大好处:

          1、良好的封装能够减少耦合。

           2、类内部的结构可以自由修改,对于外部调用者,可以不关心内部的逻辑,只要进行调用即可

          3、可以对成员进行更精确的控制。比如针对一些内部的变量进行各种条件的判断,和对应逻辑的修改等

          4、隐藏信息,实现细节。

一个很常见的例子,也就是单例模式(写个最简单的^ ^):

public class singleton{
private singleton instance ; // private 变量
    public static singleton getInstance(){  // public 方法用来对外提供instance ,而我们可以在方法中进行各种处理,比如判空等等,外部就不用做了。
        return instance = new singleton();
    }
}

在看网上博文的时候,发现这边不错,大家可以看下:

<继承>

从已有的类中派生出新的类,我们把它称之为子类,子类继承父类的属性和行为,并能根据自己的需求扩展出新的属性和行为,提高了代码的可复用性。

继承的最主要目的也是进行代码的重用。继承中有些内容还是需要注意的,简单概括:


继承以后子类可以得到什么:

  • 子类拥有父类非private的属性和方法
  • 子类可以添加自己的方法和属性,即对父类进行扩展
  • 子类可以重新定义父类的方法,即多态里面的覆盖,后面会详述

关于构造函数:

  • 构造函数不能被继承,子类可以通过super()显示调用父类的构造函数
  • 创建子类时,编译器会自动调用父类的 无参构造函数
  • 如果父类没有定义无参构造函数,子类必须在构造函数的第一行代码使用super()显示调用



<多态>


在了解多态之前,首先需要知道方法的唯一性标识即什么是相同/不同的方法:

  • 一个方法可以由:修饰符如public、static+返回值+方法名+参数+throw的异常 5部分构成
  • 其中只有方法名和参数是唯一性标识,意即只要方法名和参数相同那他们就是相同的方法
  • 所谓参数相同,是指参数的个数,类型,顺序一致,其中任何一项不同都是不同的方法

重载:


重载是指一个类里面(包括父类的方法)存在方法名相同,但是参数不一样的方法,参数不一样可以是不同的参数个数、类型或顺序

如果仅仅是修饰符、返回值、throw的异常 不同,那这是2个相同的方法,编译都通不过,更不要说重载了


覆盖/重写:


覆盖描述存在继承关系时子类的一种行为,子类中存在和父类相同的方法,也就是方法名,参数相同。


覆盖/重写的规则:

  • 子类不能覆盖父类private的方法,private对子类不可见,如果子类定义了一个和父类private方法相同的方法,实为新增方法
  • 重写方法的修饰符一定要大于被重写方法的修饰符(public > protected > default > private)
  • 重写抛出的异常需与父类相同或是父类异常的子类,或者重写方法干脆不写throws
  • 重写方法的返回值必须与被重写方法一致,否则编译报错
  • 静态方法不能被重写为非静态方法,否则编译出错

理解了上述知识点,是时候定义多态了:

  • 多态可以说是“一个接口,多种实现”或者说是父类的引用变量可以指向子类的实例,被引用对象的类型决定调用谁的方法,但这个方法必须在父类中定义
  • 多态可以分为两种类型:编译时多态(方法的重载)和运行时多态(继承时方法的重写),编译时多态很好理解,后述内容针对运行时多态
  • 运行时多态依赖于继承、重写和向上转型

向上转型的缺憾:

  • 只能调用父类中定义的属性和方法,对于子类中的方法和属性它就望尘莫及了,必须强转成子类类型

总结概括:

  • 当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法,但是它仍然要根据继承链中方法调用的优先级来确认方法,该优先级为:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O)