- 只需在新的类中产生现有类的对象。由于新的类是由现有的类的对象组成,被称为组合。
- 按照现有类的类型来创建新类。无需该表现有类的形式,采用现有类的形式并在其中添加新代码,被称为继承。
1、组合语法
编译器并不是简单地为每一个引用都创建默认对象,可以在代码中的下列位置进行初始化
- 在定义对象的地方。这意味着总是在构造器被调用之前被初始化。
- 在类的构造器中。
- 在正要使用这些对象之前,这种方式被称为惰性初始化。
- 使用实例初始化。
2、继承语法
- 继承发生时,会自动得到基类中所有的域和方法。
初始化基类
- 当创建了一个到处类的对象时,该对象包含了一个基类的子对象。这个子对象与直接用基类创建的对象是一样的。基类的子对象被包装在导出类对象内部。
class Art {
Art() { print("Art constructor"); }
}
class Drawing extends Art {
Drawing() { print("Drawing constructor"); }
}
public class Cartoon extends Drawing {
public Cartoon() { print("Cartoon constructor"); }
public static void main(String[] args) {
Cartoon x = new Cartoon();
}
} /* Output:
Art constructor
Drawing constructor
Cartoon constructor
*///:~
3、代理
- 将一个成员对象置于所要构造的类中,但与此同时我们在新类中暴露了该成员对象的所有方法。
public class SpaceShipDelegation {
private String name;
private SpaceShipControls controls =
new SpaceShipControls(); // 组合进来
public SpaceShipDelegation(String name) {
this.name = name;
}
// Delegated methods: 用到了所有方法
public void back(int velocity) {
controls.back(velocity);
}
public void down(int velocity) {
controls.down(velocity);
}
public void forward(int velocity) {
controls.forward(velocity);
}
public void left(int velocity) {
controls.left(velocity);
}
public void right(int velocity) {
controls.right(velocity);
}
public void turboBoost() {
controls.turboBoost();
}
public void up(int velocity) {
controls.up(velocity);
}
public static void main(String[] args) {
SpaceShipDelegation protector =
new SpaceShipDelegation("NSEA Protector");
protector.forward(100);
}
} ///:~
4、向上转型
- “新类是现有类的一种类型”
- 自己是否需要从新类向基类进行向上转型,如果必须向上转型,则继承是必要的,如果不需要,则应当好好考虑自己是否需要继承。
class Instrument {
public void play() {}
static void tune(Instrument i) {
// ...
i.play();
}
}
// Wind objects are instruments
// because they have the same interface:
public class Wind extends Instrument {
public static void main(String[] args) {
Wind flute = new Wind();
Instrument.tune(flute); // Upcasting 向上转型
}
} ///:~
5、final关键字
- 通常是指 无法改变。
- 不改变是由于设计或效率。
final数据
- 一个永远不改变的编译时常量。
- 一个在运行时被初始化的值,而你不希望它被改变。
- 一个static final的域占据一段不能改变的存储空间。
- 对于基本类型 final使数值恒不变。对于对象,引用恒不变。但对象本身可以被修改。
- 参数也可以final修饰,修饰后无法更高这个引用。
final方法
- 把方法锁定,防止任何继承类修改它的含义。
- 类中所有的private方法都隐式地制定为final。
final类
- 不打算继承该类,而且也不允许别人这样做。
- final类禁止继承,所以final类中所有的方法都隐式指定为final,无法覆盖。
6、初始化及类的加载
- 一般可以说 类的代码在初识使用时才加载。这通常是指加载发生于创建类的第一个对象之时,但是当访问static域或static方法时,也会发生加载。
class Insect {
private int i = 9;
protected int j;
Insect() {
print("i = " + i + ", j = " + j);
j = 39;
}
private static int x1 =
printInit("static Insect.x1 initialized");
static int printInit(String s) {
print(s);
return 47;
}
}
public class Beetle extends Insect {
private int k = printInit("Beetle.k initialized");
public Beetle() {
print("k = " + k);
print("j = " + j);
}
private static int x2 =
printInit("static Beetle.x2 initialized");
public static void main(String[] args) {
print("Beetle constructor");
Beetle b = new Beetle();
}
} /* Output:
static Insect.x1 initialized
static Beetle.x2 initialized
Beetle constructor
i = 9, j = 0
Beetle.k initialized
k = 47
j = 39
*///:~
这个例子里,
- 类里面的static成员先初始化了
- 构造器开始初花,导出类还会去找基类的初始化
- 类里面的非静态成员初始化
网友评论