日常开发过程中,我们程序猿更多时候会自嘲
CV工具人,这是因为在业务逻辑开发时,重复代码太多了,如果真的要去全盘
Copy的话,会显得很
Low,这样我们就会想到复用代码,既省时又简洁。
那我们这里就会提及复用类的两种方法:①
组合、②
继承
语法
将对象引用置于新类成员变量位置;
/**
* @author plm
* @create 2021/3/4 23:01
*/
class Pen {
private String s;
public Pen() {
System.out.println("Pen Construct.");
s = "Construct"; // 在类的构造器中
}
@Override
public String toString() {
return "Pen{" +
"s='" + s + '\'' +
'}';
}
}
public class Desk {
private String
s1 = "World", // 在定义对象的地方
s2 = "Peace",
s3,
s4;
private Pen pen;
private int i;
private float f;
public Desk() {
System.out.println("Desk Construct.");
s3 = "Hello";
f = 2.43F;
pen = new Pen();
}
{
i = 45; // 使用实例初始化
}
@Override
public String toString() {
if (s4 == null) {
s4 = "Hi"; // 惰性初始化(懒加载)
}
return "Desk{" +
"s1='" + s1 + '\'' +
", s2='" + s2 + '\'' +
", s3='" + s3 + '\'' +
", s4='" + s4 + '\'' +
", pen=" + pen +
", i=" + i +
", f=" + f +
'}';
}
public static void main(String[] args) {
Desk desk = new Desk();
System.out.println(desk.toString());
}
}
/* 输出
Desk Construct.
Pen Construct.
Desk{s1='World', s2='Peace', s3='Hello', s4='Hi', pen=Pen{s='Construct'}, i=45, f=2.43}
*/
初始化时机
如上代码,有以下几处位置:
在定义对象的地方;(总是可以在构造方法被调用之前初始化)
在类的构造方法中;
在使用到对象之前才会初始化,称为
惰性初始化;(不必每次new对象就初始化,可以减少额外的开销)
使用实例初始化;
语法
关键字
extends,从现有类获得继承信息(所有的域和方法)构建出新类;
/**
* @author plm
* @create 2021/3/4 23:40
*/
class Dword {
public Dword() {
System.out.println("Dword Construct.");
}
void dp() {
System.out.println("dp.");
}
}
class Nword extends Dword {
public Nword(int i) {
System.out.println("Nword Construct.");
}
void dp_1() {
System.out.println("dp_1.");
}
}
public class Sword extends Nword {
private int i = 7;
public Sword(int i) {
super(i);
System.out.println("Sword Construct.");
}
void dp_2() {
super.dp();
super.dp_1();
System.out.println("dp_2.");
}
public static void main(String[] args) {
Sword sword = new Sword(6);
sword.dp();
sword.dp_1();
sword.dp_2();
}
}
/* 输出
Dword Construct.
Nword Construct.
Sword Construct.
dp.
dp_1.
dp.
dp_1.
dp_2.
*/
tips:
supper关键字表示超类,想要调用基类的方法可使用
supper.基类方法名()即可;
初始化基类
导出类进行初始化时,会先调用
supper调用基类的构造方法进行初始化(此为
隐式地调用基类的无参构造);
基类在导出类访问它之前就已经完成了初始化;
带参的构造方法
必须使用关键
supper 显示地调用基类构造方法(如上代码),否则编译器就会提醒你:
There is no default constructor available in 'cn.peiluming.test2.test1.Nword'
方法重写
既然子类拥有了父类的所有方法,那如果需要
对父类方法进行自定义实现,这里就会涉及到
重写,也是后面
多态的前提之一
JDK 1.5 之后引入注解
@Override,对你的重写方法进行校验;
组合一般多用于
Has-a,在新的类中使用现有类的属性,而并非它的方法;多加上
private修饰符!
继承多用于
Is-a,常常结合向上转型使用,因为继承可以确保基类中的方法,在导出类中同样生效;