一、继承的概念
Java中的继承允许一个子类继承一个父类的属性和方法,这使得代码的重用更加容易。子类可以继承父类的公共、受保护和包访问权限的属性和方法。继承是面向对象编程中最基本的概念之一,其目的是减少代码的重复,并提高软件的可维护性。
通过继承,子类可以拥有和父类相同的方法和属性,同时可以重写一些方法或添加新的方法和属性。子类继承父类的同时,也可以添加自己的特性。
二、继承的基本语法
class 父类 { // 父类属性和方法的定义 } class 子类 extends 父类 { // 子类属性和方法的定义 }
在Java中,使用extends关键字来实现继承。子类通过extends关键字来引用父类,子类继承了父类的所有属性和方法。父类和子类之间的关系称为「父类 - 子类关系」或「超类 - 子类关系」。我们可以通过下面的示例代码来理解Java的继承语法。
public class Person { protected String name; protected int age; public Person(String name, int age) { this.name = name; this.age = age; } public void eat() { System.out.println("Person " + name + " is eating."); } } public class Student extends Person { private String school; public Student(String name, int age, String school) { super(name, age); this.school = school; } public void study() { System.out.println("Student " + name + " is studying in " + school); } }
上面的示例代码中,Person是父类,Student是子类。Student类继承了Person类的所有属性和方法。其中,Person类含有两个属性name和age,还有一个eat方法;Student类含有一个school属性,还有一个study方法。
三、继承中的方法覆盖
子类可以重写父类的方法,这被称为方法覆盖或重写(Overriding)。覆盖方法必须与父类的方法的名称、参数列表和返回类型相同,并且访问权限可以更严格,不能更宽松。可以使用@Override注释来标识一个方法是覆盖的方法。
下面的示例代码展示了方法覆盖的情况:
public class Vehicle { public void move() { System.out.println("Vehicle is moving."); } } public class Car extends Vehicle { @Override public void move() { System.out.println("Car is moving."); } } public class Main { public static void main(String[] args) { Vehicle vehicle = new Vehicle(); Vehicle car = new Car(); vehicle.move(); car.move(); } }
在这个示例中,Vehicle是父类,Car是子类。Vehicle和Car都有move()方法,但Car覆盖了Vehicle的move()方法,并且只打印"Car is moving."。在main()方法中,声明了一个Vehicle类型的变量vehicle和一个Vehicle类型的变量car(但引用的是一个Car对象)。调用vehicle.move()方法将输出"Vehicle is moving.",而调用car.move()方法将输出"Car is moving.",因为car引用的是Car对象,所以调用的是Car类的move()方法。
四、继承中的构造函数
当一个子类被创建后,其父类的构造函数也会被调用。子类的构造函数可以调用父类的构造函数,以设置继承的属性。在Java中,使用super关键字来引用父类的构造函数。
使用继承的构造函数的示例代码如下:
public class Animal { protected String name; public Animal(String name) { this.name = name; } } public class Dog extends Animal { private String breed; public Dog(String name, String breed) { super(name); this.breed = breed; } }
在这个示例中,Animal是父类,Dog是子类。Dog类有一个构造函数,接受name和breed参数,该构造函数首先使用super(name)调用Animal的构造函数,并将name传递给它。然后,它为breed属性设置了一个值。
五、继承中的访问修饰符
在Java中,存在四种访问修饰符,分别为:public、protected、default、private。这些访问修饰符可以用来限制属性和方法的访问权限。在继承中,对于父类中定义的成员,子类可以访问到除了private的其他访问修饰符的成员。
下面的代码示例展示了继承中访问修饰符的使用:
public class Animal { public String name; protected int age; String color; private int weight; public Animal(String name, int age, String color, int weight) { this.name = name; this.age = age; this.color = color; this.weight = weight; } public void eat() { System.out.println(name + " is eating."); } protected void sleep() { System.out.println(name + " is sleeping."); } void run() { System.out.println(name + " is running."); } private void breathe() { System.out.println(name + " is breathing."); } } public class Dog extends Animal { public Dog(String name, int age, String color, int weight) { super(name, age, color, weight); } public void showInfo() { System.out.println("Name: " + name); System.out.println("Age: " + age); System.out.println("Color: " + color); // System.out.println("Weight: " + weight); // 无法访问 eat(); // public方法可以访问 sleep(); // protected方法可以访问 run(); // default方法可以访问 // breathe(); // 无法访问 } }
在上面的示例代码中,Animal类有四个成员变量,分别为public、protected、default和private修饰。Dog类是Animal类的子类,在showInfo()方法中,Dog类可以访问到Animal类四个成员变量中除了private修饰的成员变量。另外,在showInfo()方法中,可以访问public和protected修饰的方法,但无法访问default和private修饰的方法。
六、总结
通过本文对Java子类继承父类的所有属性和方法的多个方面的介绍,我们可以了解到Java中继承的一些基本概念和使用方法。继承机制是面向对象编程中的重要特性,合理地使用继承可以简化代码的编写和维护,并且提高代码的可读性和可扩展性。