Bootstrap

【Java面向对象】继承

1.概念

在 Java 术语中,如果类口继承自另一个类 C2, 那么就将口称为子类 ( subclass), 将C2 称为超类 ( 超类也称为父类 ( parent class) 或基类 ( baseclass), 子类又称为继承类 ( extended class) 或派生类 ( derived )
一个类定义了一个类型。由子类定义的类型称为子类型 ( subtype), 由父类定义的类型称为父类型

子类从它的父类中继承可访问的数据域和方法,还可以添加新的数据域和方法。
子类并不是父类的一个子集。实际上,一个子类通常比它的父类包含更多的信息和方法。
父类中的私有数据域在该类之外是不可访问的。因此,不能在子类中直接使用。但是,如果父类中定义了公共的访问器/修改器,那么可以通过这些公共的访问器/修改器来访问 /修改它们
某些程 序设计语言是允许从几个类派生出一个子类的。这种能力称为多重继承,但是在 Java 中是不允许多重继承的。
一个 Java 类只可能直接继承自一个父类。这种限制称为单一继承如果使用 extends 关键字来定义一个子类,它只允许有一个父类。然而,多重继承是可以通过接口来实现的。

public class Person{
	private String name;
	private boolean isMale;
	public Person(String name,boolean isMale){
		this.name = name;
		this.isMale = isMale;
	} 
	public void setName(String name){
		this.name = name;
	}
	public void setSex(boolean isMale){
		this.isMale = isMale;
	}
}

public class Boss extends Person{
	private int salary;
	public Person(int salary){
		this.salary = salary;
	}
	public Person(int salary,String name,boolean isMale){
		this.salary = salary;
		setName(name); // 不能this.name,因为访问不到
		setSex(isMale);
	}
}

2.super

关键字 super 指代父类,可以用于调用父类中的普通方法和构造方法。

2.1 调用父类的构造方法

构造方法用于构建一个类的实例。不同于属性和普通方法,父类的构造方法不会被子类继承。它们只能使用关键字 super 从子类的构造方法中调用。
语句 super()调用父类的无参构造方法,而语句 super(arguments) 调用与 arguments 匹配的父类的构造方法。语句 super()或 super(arguments) 必须出现在子类构造方法的第一行,这是显式调用父类构造方法的唯一方式。要调用父类的构造方法就必须使用关键字 super, 而且这个调用必须是构造方法的第一条语句。在子类中调用父类构造方法的名字会引起一个语法错误。
构造方法可以调用重载的构造方法或父类的构造方法。如果它们都没有被显式地调用,编译器就会自动地将 作为构造方法的第一条语句。

在任何情况下,构造一个类的实例时,将会调用沿着继承链的所有父类的构造方法。当构造一个子类的对象时,子类的构造方法会在完成自己的任务之前,首先调用它的父类的构造方法。如果父类继承自其他类,那么父类的构造方法又会在完成自己的任务前,调用它自己的父类的构造方法。这个过程持续到沿着这个继承层次结构的最后一个构造方法被调用为止。这就是构造方法链。

class Fruit{
	String name;
	int weight;
	public Fruit(String name,int weight){
		this.name = name;
		this.weight = weight;
	}
}

class Person{
	private int age;
	public Person(int age){
		this.age = age;
	}
}

class Worker extends Person{
	private int salary;
	public Worker(int age,int salary){
		super(age);
		this.salary = salary;
	}
	public Worker(){
		this(0,0);
	}
}

class Teacher extends Worker{
	private Fruit fruit;
	private int students;
	public Teacher(int age,int salary,String name,int weight,int students){
	// 父类的
	super(age,salary);
	// 包含的类
	fruit = new Fruit(name,weight);
	// 子类的
	this.students = student;
	}	
}

2.2 调用父类的普通方法

super 不仅可以引用父类的构造方法,也可以引用父类的方法:
super. 方法名 (参数);

3.方法重写

子类从父类中继承方法。有时,子类需要修改父类中定义的方法的实现,这称为方法重写 (method overriding)。

  • 重写的方法必须与被重写的方法具有一样的签名,以及一样或者兼容的返回类型。
    兼容的含义是重写方法的返回类型可以是被重写方法的返回类型的子类型。
  • 仅当实例方法可访问时,它才能被重写。因为私有方法在它所处的类本身以外是不能访问的,所以它不能被重写。如果子类中定义的方法在父类中是私有的,那么这两个方法完全没有关系。
  • 与实例方法一样,静态方法也能被继承。但是,静态方法不能被重写。如果父类中定义的静态方法在子类中被重新定义,那么在父类中定义的静态方法将被隐藏。可以使用语法 “父类名.静态方法名 (SuperClassName.staticMethodName)” 调用隐藏的静态方法。

注意重载和重写的区别:
1.方法重写发生在具有继承关系的不同类中;方法重载可以发生在同一个类中,也可以发生在具有继承关系的不同类中。
2.方法重写具有同样的签名;方法重载具有同样的名字但是不同的参数列表。

重写时,为了避免错误,可以使用一种特殊的 Java 语法,称为重写标注 ( override annotation),在子类的方法刖面放一个@Override。
该标注表示被标注的方法必须重写父类的一个方法。如果具有该标注的方法没有重写父类的方法,编译器将报告一个错误。

调用同名函数时,调用顺序:子类且类型匹配的>子类且类型利用隐式转换之后匹配的>父类且类型匹配的>父类且类型利用隐式转换之后匹配的

4.Object 类及其 toString()

如果在定义一个类时没有指定继承,那么这个类的父类默认是Object。
Object类的对象有toString()方法。
调用一个对象的 toString()会返回一个描述该对象的字符串。默认情况下,它返回一个由该对象所属的类名、at 符号 (@) 以及用十六进制形式表示的该对象的内存地址组成的字符串。

通常,应该重写这个 toString 方法,以返回一个代表该对象的描述性字符串。

也可以传递一个对象来调用 System.out.println(object) 或 System,out.print(object) 这等价于调用 System.out.println(object.toString()) 或System.out.print(object.toString()) 。

;