1. 封装
封装概述
是指隐藏对象的属性和实现细节,仅对外提供公共访 问方式。
好处
隐藏实现细节,提供公共的访问方式
提高了代码的复用性 提高安全性。
封装原则
将不需要对外提供的内容都隐藏起来。
把属性隐藏,提供公共方法对其访问。
2. 继承
继承概述
多个类中存在相同属性和行为时,将这些内容抽取到一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
通过extends关键字可以实现类与类的继承
继承格式:class 子类名 extends 父类名 {}
抽取出来的这个类称为父类,基类或者超类;而继承这个抽取出来的类的为子类或者派生类。
好处
提高代码的复用性
提高了代码的维护性
让类与类之间产生了关系,是多态的前提 (但同时增强了类之间的耦合性)
原则
JAVA支持单继承,不支持多继承。
JAVA支持多层继承。
子类在继承父类的时候,只能继承父类所有的非私有成员。
子类不能继承父类的构造方法,但可以通过super关键字访问父类的构造方法。
永远不要为了功能而去继承,继承是在类之间存在所属关系( is a )的时候才去继承的。
super与this
当本类的成员和局部变量同名用 this 区分。
当子父类中的成员变量同名用 super 区分父类。
this: 代表一个本类对象的引用。
super:代表一个父类空间。
子父类构造函数
子类的所有构造方法默认都会访问父类中的空参构造方法。所以每一个构造方法的第一句默认都是super();
因为子类会继承父类的成员,有可能会用到父类的数据,所以子类初始化之前会先初始化父类。
如果父类没有空参构造函数,需要子类通过super去显示的调用父类的有参构造函数。
且通过super或者this关键字初始化类时,super();或者this();必须要放到第一句。
package com.hpe.sort;
class Father{// 父类
private String name;
Father(String name){
this.name = name;
}
public void eat() {
System.out.println("Father eat!" + this.name);
}
}
class Son extends Father{// 子类继承父类
private String school;
Son(String name) {
super(name);
}
Son(String name, String school) {
/*
如果super()和 this()同时写入,会直接报错
Constructor call must be the first statement in a constructor
*/
super(name); // 显示调用父类构造函数
// this(name);// 调用本类的其他构造函数
this.school = school;
}
public void eat() {
System.out.println("Son eat!" + school);
}
}
public class ExtendsClass {
public static void main(String[] args) {
Son son1 = new Son("Jack");
son1.eat();
Son son2 = new Son("Tom", "TUNS");
son2.eat();
}
}
子父类普通方法
子类中出现了和父类中一模一样的方法声明,也被称为方法覆盖,方法复写。
如果方法名不同,就调用对应的方法
如果方法名相同,最终使用的是子类自己的
方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能 ,又定义了子类特有的内容。
方法重写的注意事项
父类中私有方法不能被重写
子类重写父类方法时,访问权限不能更低
父类静态方法,子类也必须通过静态方法进行重写
方法重写与重载的区别
overload (重载):同一个类中。多个方法名相同,参数列表不同。
override (重写):子类中。方法同名,参数列表相同
class Father{// 父类
public void eat() {
System.out.println("Father eat!");
}
}
class Son extends Father{// 子类
public void eat() { // 重写父类的 eat() 方法
System.out.println("Son eat!");
}
public void eat(String food) {// 重载子类的 eat() 方法
System.out.println("Son eat " + food);
}
}
final关键字
final关键字是最终的意思,可以修饰类,成员变量,成员方法。
修饰类,类不能被继承。提高安全性,提高程序的可读性
修饰变量,变量就变成了常量,只能被赋值一次,且必须在声明的同时或在每个构造方法中或代码块中显式赋值
修饰方法,方法不能被重写
final修饰局部变量
在方法内部,该变量不可以被改变
在方法声明上:1. 基本类型,是值不能被改变;2. 引用类型,是地址值不能被改变
final、finally、finalize()之间的区别?
3. 多态
多态概述
某一个事物,在不同时刻表现出来的不同状态。
多态前提和体现
1. 有继承关系
2. 有方法重写
3. 有父类引用指向子类对象
成员访问特点
成员变量:编译看左边,运行看左边
成员方法:编译看左边,运行看右边
静态方法:编译看左边,运行看左边(静态与类相关,算不上重写。所以,访问的还是左边的)
class Father{// 父类
public int num = 100;
public void eat() {
System.out.println("Father eat!");
}
public static void function() {
System.out.println("Father function");
}
}
class Son extends Father{// 子类
public int num = 200;
public int num2 = 300;
public void eat() { // 重写父类的 eat() 方法
System.out.println("Son eat!");
}
public static void function() {
System.out.println("Son function");
}
public void run() {
System.out.println("Son run");
}
}
public class ExtendsClass {
public static void main(String[] args) {
// 父类引用指向子类对象
Father f = new Son();
System.out.println(f.num);
// System.out.println(f.num2); // 编译错误:num2 cannot be resolved or is not a field
f.eat();
// f.run(); // 编译错误:The method run() is undefined for the type Father
f.function();
}
}
运行结果:
多态的好处
提高了程序的维护性(由继承保证)
提高了程序的扩展性(由多态保证)
多态的弊端
不能访问子类特有功能(可以利用向下转型访问子类的功能)
向上转型
从子到父:父类引用指向子类对象
向下转型
从父到子:父类引用转为子类对象