文章目录
- 7.1 组合语法
- 7.2 继承语法
- 初始化基类
- 7.3 代理
- 7.4 重载与覆写
- 7.7 向上转型
- 7.8 final关键字:这是无法改变的
- final数据
- 空白final
- final 参数
- final方法
- final类
- 7.9 初始化及类的加载
- 7.10 总结
7.1 组合语法
将对象的引用置于新类中。
public class Person {
private int age;
private String name; // 对象引用默认为null
private Animal a1; // 对象引用默认为null
}
7.2 继承语法
创建一个类时总是在继承,除非明确指出要继承的类,否则隐式继承Object。
子类无法看到父类方法的具体定义,因此,可以将继承视为是对类的复用。
public class Man extends Person {
// 使用父类方法
// 增加新方法
// 修改父类方法,同时调用父类方法(super)
}
初始化基类
当创建一个导出类的对象时,该对象包含了一个基类的子对象。这个子对象与用基类直接创建的对象是一样的。只是基类的子对象被包装在导出类对象内部。Java会自动在导出类的构造器中插入对基类的无参构造器,如果基类没有无参构造器,就需要在导出类的构造方法中指定基类的有参构造器。
可以在构造方法的第一个表达式调用当前类的其它构造方法或者在第一个表达式调用父类的构造方法。但两者不能同时调用。
public class Person {
Person() {
this("a");
// this(1); 报错,调用其他构造方法必须在第一个表达式
System.out.println("person...");
}
Person(int i) {
System.out.println(i);
}
Person(String s) {
System.out.println(s);
}
}
public class Man extends Person {
Man() {
// super(); 编译器默认会调用基类的无参构造器,如果没有无参构造器需要指定有参构造器
super(i); // 指定调用基类的有参构造器
System.out.println("man...");
}
public static void main(String[] args) {
Man man = new Man();
}
}
7.3 代理
组合:与调用类之间关系不紧密
继承:与父类关系紧密,会暴露父类的所有方法
代理:以组合的形式调用父类,有选择性的暴露接口
public class Man {
private Person person = new Person();
void fly() {
person.fly();
}
void eat() {
person.eat();
}
public static void main(String[] args) {
Man man = new Man();
man.fly();
man.eat();
}
}
7.4 重载与覆写
重载 overload:相同方法名,不同参数
覆写 override: 同一个方法。
使用@Override标注覆写一个方法,如果不小心重载会报错。
7.7 向上转型
Person p1 = new Man();
p1.eat(); // Man是Person的子类,p1对象可以调用Person具有的方法不能调用Man特有的方法
7.8 final关键字:这是无法改变的
final数据
- 基本数据类型,数值恒定不变,定义的时候必须赋值。
- 对象引用,引用恒定不变,定义的时候必须赋值。(对象自身是可以变的)
public class Person {
public final int I1 = 10;
public final int I2;
{
// 非静态方法块
i2 = 20;
}
public final Map<String, String> map = new HashMap<>();
public void main(String[] args) {
Person p = new Person();
p.map.put("a", "b");
System.out.println(p.map);
}
}
空白final
Java允许在定义时不初始化,而是在构造器中初始化。
public class Person {
final String name;
final String[] bbb;
Mna() {
this.name = "未命名";
this.bbb= new String[]{ "a", "b" };
}
Man(String name, String[] bbb) {
this.name = name;
this.bbb = bbb;
}
public static void main(String[] args) {
Man man = new Man();
}
}
final 参数
Java允许在参数列表中以声明的方式将参数指明为final。无法在方法中更改参数引用所指向的对象。
public class Man {
Man(final String a, int b) {
// a = "aa"; 错误
b = 1;
}
public static void main(String[] args) {
Man man = new Man("a", 1);
}
}
final方法
将方法锁定,防止任何继承类覆写它。当子类能够调到父类的方法时才算是覆写了父类的方法,如果因为权限控制调不到,则相当于定义了一个新的方法。
final类
不允许拥有子类。
因为final类不允许拥有子类,因此相当于方法也是final的,即不会被子类覆写。
7.9 初始化及类的加载
1 父类的static字段(加载父类)
2 子类的static字段(加载子类)
3 main方法
4 父类的常规字段(初始化父类)
5 父类的构造器主体(初始化父类)
6 子类的常规字段(初始化子类)
7 子类的构造器主体(初始化子类)
public class Person {
int a;
static int b = InitPersonB();
static int InitPersonB() {
System.out.println("Person static int b....");
return 100;
}
public Person() {
System.out.println("Person person...." + "a...." + a);
a = 100;
System.out.println("Person person...." + "a...." + a);
}
}
public class Man extends Person{
int a;
static int b = InitManB();
static int InitManB() {
System.out.println("Man static int b....");
return 1000;
}
public Man() {
System.out.println("Man man...." + "a...." + a);
a = 100;
System.out.println("Man man...." + "a...." + a);
}
public static void main(String[] args) {
System.out.println("Man main....");
Man man = new Man();
}
}
7.10 总结
在开始一个设计时,一般应优先选择使用组合(或代理)。
对于继承,导出类具有基类接口,可以向上转型至基类,对于多态至关重要。