一、继承的概念
继承是面向对象编程中的一个重要概念。它允许我们创建新的类(子类),从已有的类(父类)中继承其属性和方法。这样,子类就具有了父类的所有属性和方法,还可以在此基础上添加些许新的属性和方法。
Java中,默认情况下,每个类都是Object类的子类,因此Java中大多数类都继承了Object提供的属性和方法。
二、Java中继承的实现
在Java中,继承可以通过“extends”关键字来实现,使用该关键字后,子类可以从父类中继承所有的非私有(private)属性和方法。
// 定义父类Person public class Person { public String name; public int age; public void sayHello() { System.out.println("Hello, I am " + name); } } // 定义子类Student,继承Person public class Student extends Person { public String school; public void study() { System.out.println(name + " is studying in " + school); } } // 测试,从Student中调用继承自Person中的方法和属性 public class Test { public static void main(String[] args) { Student student = new Student(); student.name = "Li Lei"; student.age = 18; student.school = "No.1 High School"; student.sayHello(); // Hello, I am Li Lei student.study(); // Li Lei is studying in No.1 High School } }
三、访问修饰符对继承的影响
Java中有四个访问修饰符:public、protected、default、private。它们的作用范围不同,如果使用不当,会对继承产生影响。
1. public
使用public修饰的属性和方法可以被子类直接访问,例如:
// 父类Student中使用public修饰的属性和方法 public class Person { public String name; public int age; public void sayHello() { System.out.println("Hello, I am " + name); } } // 子类Student中直接访问继承自父类Person中使用public修饰的属性和方法 public class Student extends Person { public void sayHelloToTeacher() { System.out.println("Hello, Teacher"); sayHello(); // 调用继承自Person中使用public修饰的方法 System.out.println("My name is " + name); // 访问继承自Person中使用public修饰的属性 } }
2. protected
使用protected修饰的属性和方法可以被子类访问,但是对于子类的外部类或无关类是不可见的。这意味着,子类可以在子类内部或其子类内部使用父类中的受保护成员,但是在子类外部不可使用。
// 父类Person中使用protected修饰的属性和方法 public class Person { protected String name; protected int age; protected void sayHello() { System.out.println("Hello, I am " + name); } } // 子类Student中调用继承自父类Person中使用protected修饰的方法 public class Student extends Person { public void sayHelloToTeacher() { System.out.println("Hello, Teacher"); sayHello(); // 调用继承自Person中使用protected修饰的方法 System.out.println("My name is " + name); // 访问继承自Person中使用protected修饰的属性 } } // 无关类中无法访问继承自Person中使用protected修饰的属性和方法 public class Test { public static void main(String[] args) { Person person = new Person(); person.name = "Tom"; // 编译错误,无法访问使用protected修饰的属性 person.sayHello(); // 编译错误,无法访问使用protected修饰的方法 } }
3. default
不使用访问修饰符,即使用默认访问修饰符声明的属性和方法,对于子类和同一包中的其他类都是可见的。但是,对于不在同一包中的类,使用default修饰的属性和方法都是不可见的。
// 父类Person中使用默认访问修饰符声明的属性和方法 public class Person { String name; int age; void sayHello() { System.out.println("Hello, I am " + name); } } // 子类Student中会继承从父类Person中使用default访问修饰符声明的属性和方法 public class Student extends Person { public void sayHelloToTeacher() { System.out.println("Hello, Teacher"); sayHello(); // 调用继承自Person中使用default访问修饰符声明的方法 System.out.println("My name is " + name); // 访问继承自Person中使用default访问修饰符声明的属性 } } // 另一个类,在同一包中可以访问使用default访问修饰符声明的属性和方法 public class AnotherClass { public void test(Person person) { person.name = "Alex"; // 可以访问使用default访问修饰符声明的属性 person.sayHello(); // 可以访问使用default访问修饰符声明的方法 } } // 不在同一包中的类无法访问使用default访问修饰符声明的属性和方法 public class Test { public static void main(String[] args) { Person person = new Person(); person.name = "Tom"; // 编译错误,无法访问使用default访问修饰符声明的属性 person.sayHello(); // 编译错误,无法访问使用default访问修饰符声明的方法 } }
4. private
使用private修饰的属性和方法只能被该类的内部访问,其他类无法访问。因此,私有成员是不可继承的,子类中无法访问父类的私有属性和方法。
// 父类Person中使用private修饰的属性和方法 public class Person { private String name; private int age; private void sayHello() { System.out.println("Hello, I am " + name); } } // 子类Student中无法访问从父类Person中继承的私有成员 public class Student extends Person { public void sayHelloToTeacher() { System.out.println("Hello, Teacher"); sayHello(); // 编译错误,无法访问继承自Person中的私有方法 System.out.println("My name is " + name); // 编译错误,无法访问继承自Person中的私有属性 } }
四、super关键字
在子类中如果想要调用父类中的方法或属性,可以使用super关键字。使用super关键字可以访问父类的成员变量和成员方法,并且可以调用父类的构造函数。
// 父类Person中的构造函数 public class Person { public String name; public int age; public Person(String name, int age) { this.name = name; this.age = age; } } // 子类Student中使用super关键字访问父类的构造函数 public class Student extends Person { public String school; public Student(String name, int age, String school) { super(name, age); // 调用父类的构造函数 this.school = school; } } // 测试 public class Test { public static void main(String[] args) { Student student = new Student("Li Lei", 18, "No.1 High School"); System.out.println(student.name); // 输出:"Li Lei" System.out.println(student.age); // 输出:18 System.out.println(student.school); // 输出:"No.1 High School" } }
五、总结
继承是面向对象编程中的重要概念,它允许子类继承父类的所有属性和方法,并且可以在此基础上添加些许新的属性和方法。在Java中,使用extends关键字可以实现继承,子类可以从父类中继承所有的非私有属性和方法。在使用过程中,访问修饰符对于继承有一定的影响,如public修饰的属性和方法可以被子类直接访问,而private修饰的成员是不可继承的。使用super关键字可以访问父类的构造函数和成员变量,同时也可以调用父类的方法。