继承
什么是继承?
继承是面向对象的三大特征之一,多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
如何实现继承?
Java中使用extends关键字实现类的继承机制,其语法规则为:
class 子类名 extends 父类名{}
- 通过继承,子类自动拥有父类(基类)放入所有成员(成员变量和方法)。
- Java只支持单继承,不孕育多继承:一个子类只能有一个父类,一个父类可以派生出多个子类。
示例
//父类Person
class Person{
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
//子类Student
class Student extends Person{
private String school;
public String getSchool(){
return school;
}
public void setSchool(String school){
this.school=school;
}
}
public class TestPerson {
public static void main(String arg[]){
Student s = new Student();
s.setName("John");
s.setAge(18);
s.setSchool("SCH");
System.out.println(s.getName());
System.out.println(s.getAge());
System.out.println(s.getSchool());
}
}
权限修饰符(private、default、protected、public)
- Java权限修饰符置于类的成员定义前,用来限定其他对象对该类对象成员的访问权限。
- private私有的;
- default默认的;
- protected受保护的;
- public公共的;
修饰符 | 类内部 | 同一个包 | 子类 | 任何地方 |
---|---|---|---|---|
private | Y | |||
default | Y | Y | ||
protected | Y | Y | Y | |
public | Y | Y | Y | Y |
- 对于class的权限修饰只可以用public和default
- public类可以在任意地方被访问
- default类只可以在同一个包内部的类访问
方法的重写
什么是方法重写?
方法重写就是子类中出现了和父类中一模一样的方法声明,也可称为方法覆盖,方法复写。例:如果父类是鸟类,鸟类中有飞翔的方法,子类是鸵鸟,父类中飞翔的方法子类不适用,所以鸵鸟类就要重写飞翔这个方法。
方法重写的注意事项
- 重写方法必须和被重写方法具有相同的方法名称、参数列表和返回类型。
- 重写方法不能使用比被重写方法更严格的访问权限,也就是子类的权限不能比父类的权限级别低,最好权限一致。
- 父类中私有的方法不能被重写,因为父类私有方法子类根本就无法继承。
super关键字
当父类中的方法被子类的方法覆盖,子类的对象将无法访问父类中被覆盖的方法,但是在子类方法中可以调用父类中被覆盖的方法。使用super关键字或者父类类名作为调用者来调用父类中被覆盖的方法。(父类类名作为调用者时,需考虑权限)
class FatherClass{
public int value;
public void f(){
value = 100;
System.out.println("FatherClass.value="+value);
}
}
class ChildClass extends FatherClass{
public int value;
public void f() {
super.f();
value = 200;
System.out.println("ChildClass.value=" + value);
System.out.println(value);
System.out.println(super.value);
}
}
public class TestInherit {
public static void main(String arg[]) {
ChildClass c = new ChildClass();
c.f();
}
}
输出:
FatherClass.value=100
ChildClass.value=200
200
100
继承中的构造方法
- 子类的构造过程中必须调用其父类的构造方法
- 子类可以在自己的构造方法中使用super(argument_list)调用父类的构造方法。
- 使用this(argument_list)调用本类的另外的构造方法
- 如果调用super,必须写在子类构造方法的第一行
- 如果子类的构造方法中没有显示调用父类构造方法,则系统默认调用无参数的构造方法
- 如果子类的构造方法中既没有显示调用父类构造方法,而父类中又没有无参数的构造方法,则编译出错
class SuperClass {
private int n;
SuperClass() {
System.out.println("SuperClass()");
}
SuperClass(int n) {
System.out.println("SuperClass(" + n + ")");
this.n = n;
}
}
class SubClass extends SuperClass {
private int n;
SubClass(int n) {
//super(); //默认
this();
System.out.println("SubClass(" + n + ")");
this.n = n;
}
SubClass() {
super();
System.out.println("SubClass()");
}
}
public class TestSuperSub {
public static void main(String arg[]) {
//SubClass sc1 = new SubClass();
SubClass sc2 = new SubClass(400);
}
}
输出:
SuperClass()
SubClass()
SubClass(400)
例:构造函数与一般成员函数比较
class A {
protected void print(String s){
System.out.println(s);
}
A(){print("A()");}
public void f(){print("A:f()");}
}
class B extends A{
B(){print("B()");}
public void f(){print("B:f()");}
public static void main(String arg[]){
B b = new B(); //输出:A() B() 子类构造函数默认调用父类无参的构造方法
b.f(); //输出:B:f()
}
}
例2
package TestPersonExtend;
class Person{
private String name;
private String location;
Person(String name){
this.name = name;
location = "beijing";
}
Person(String name,String location){
this.name = name;
this.location = location;
}
public String info(){
return "name:"+name+";"+"location:"+location;
}
}
class Student extends Person {
private String school;
Student(String name,String school){
this(name,"beijing",school);
}
Student(String n,String l,String school){
super(n,l);
this.school = school;
}
public String info(){
return super.info()+";"+"school:"+school;
}
}
class Teacher extends Person {
private String professional;
Teacher(String name,String professional){
this(name,"beijing",professional);
}
Teacher(String n,String l,String professional){
super(n,l);
this.professional= professional;
}
public String info(){
return super.info()+";"+"professional:"+professional;
}
}
public class Test {
public static void main(String[] args){
Person p1 = new Person("A");
Person p2 = new Person("B","shanghai");
Student s1 = new Student("C","s1");
Student s2 = new Student("C","shanghai","s2");
Teacher t1 = new Teacher("D","professor");
System.out.println(p1.info());
System.out.println(p2.info());
System.out.println(s1.info());
System.out.println(s2.info());
System.out.println(t1.info());
}
}