记录学习Java基础中有关继承、方法重写、构造器调用的基础知识,学习继承之前建议学习static关键字的内容【自学笔记】01Java基础-09Java关键字详解
不可以的,子类有自己的构造器,父类构造器用于初始化父类对象。
可以的,只是不能直接访问。
具体表现如下:
例如,在父类中有一个私有变量,并且提供了一个公共的getter和setter方法,那么子类就可以通过调用这些方法来读取和设置该私有变量的值。
有争议的知识点。
子类可以直接使用父类的静态成员(共享)
但个人认为:子类不能继承父类的静态成员。(共享并非继承)
Java中,静态成员(包括静态变量和静态方法)是与类关联的,而不是与对象实例关联。因此子类可以直接访问父类的静态成员,但不会重新创建或覆盖这些成员。
public class Parent {
public static int count = 0;
// 静态方法
public static void incrementCount() {
count++;
}
}
public class Child extends Parent {
// 子类无需定义count,直接可以使用Parent.count
public static void main(String[] args) {
// 直接通过类名访问父类的静态成员
System.out.println(Parent.count); // 输出:0
Parent.incrementCount();
System.out.println(Parent.count); // 输出:1
System.out.println(Child.count); // 输出:1,因为Child和Parent共享同一个静态变量count
}
}
在这个例子中,Child
类和 Parent
类共享同一个 count
变量。同样,Child
类也可以调用 Parent
中的public静态方法 incrementCount()
。但是,子类不能重写父类的静态方法,只能重新声明一个同名的静态方法,这将被视为一个新的方法而非覆盖。
满足就近原则。
当子类中方法或变量与父类重名时,会优先使用子类的,此时如何指定使用父类的方法或变量?
可以通过super.父类成员变量/父类成员方法
,指定访问父类的成员。了解super关键字
子类中想声明与父类同名的变量时有两种情况:
类名.变量
,可以查看了解static关键字public class Parent {
public static int count = 10;
}
public class Child extends Parent {
public static int count = 20;
public static void main(String[] args) {
System.out.println(Parent.count); // 输出:10
System.out.println(Child.count); // 输出:20
}
}
this
关键字来获取当前作用域内的非静态变量,用super
来获取父类的非静态变量。public class Parent {
public int count = 10;
}
public class Child extends Parent {
public int count = 20; // 子类中声明了与父类同名的实例变量
public void displayCounts() {
System.out.println("Parent count: " + super.count);
System.out.println("Child count: " + this.count);
}
public static void main(String[] args) {
Child child = new Child();
child.displayCounts(); // 输出:
// Parent count: 10
// Child count: 20
}
}
public class Animal {
public void makeSound() {
System.out.println("动物发出叫声");
}
}
public class Dog extends Animal {
@Override // 标注此方法是重写父类Animal的makeSound方法
public void makeSound() {
System.out.println("狗叫汪汪汪");
}
}
在上方示例代码中,重写的方法makeSound()
上方出现了@Override注解。
复习构造器的概念 > 封装-构造方法
子类并不继承父类的构造器,而是在自己构造器调用父类构造器来初始化从父类继承而来的成员变量。
super
关键字在构造器内部明确调用父类的一个构造器,从而初始化父类的状态。super();
必须是子类构造器中第一行,并且一个构造器中只能出现一次。如果显示写明就是显式调用,如果没写也会存在,为隐式调用。super()
的"()"
中可以填入参数,以此调用父类有参构造器,将会通过指定的参数名称、数量、排序来判断调用的父类中的哪个有参构造器。显式调用:
public class Parent {
public int value;
// 父类构造器
public Parent(int value) {
this.value = value;
}
}
public class Child extends Parent {
public String name;
// 显式调用父类构造器
public Child(int parentValue, String childName) {
super(parentValue); // 调用Parent类的构造器
this.name = childName;
}
“super();”
。隐式调用:
// 若不显式调用,则会默认调用父类无参构造器(若存在)
// 如果Parent类没有无参构造器,则此处会出错,需要显示调用带参构造器
public Child(String childName) {
//super();//第一句默认调用父类无参构造器,即使不写也默认存在
this.name = childName;
}
}
前言:
我们知道在实体类中没有定义任何构造器时,系统会自动提供一个默认(无参)构造器。
一旦定义了至少一个构造器(无论是否有参数),Java编译器将不再自动提供无参构造器。这时若需无参构造器来创建对象,那么必须手动提供一个无参构造器,否则将会报错。
所以子类构造器调用父类有以下情况:
super(...)
至少一个有参构造器,否则因为无法找到默认无参构造器报错。this 关键字:
this
可以用来引用当前对象的属性或方法:class Person {
String name;
public Person(String name) {
this.name = name; // 使用 this 引用当前实例对象的 name 属性,并将传入的形参name赋值给它
}
public void showName() {
System.out.println(this.name); // 使用 this 引用当前对象的 name 属性
}
}
this
用于区分二者:class MyClass {
int value;
public void setValue(int value) {
this.value = value; // 设置的是成员变量 value,而不是方法参数
}
}
this
还可以作为方法或构造器的参数传递当前对象引用:class AnotherClass {
public void process(MyClass obj) {
//...
}
public void callProcess() {
process(this); // 将当前对象自身作为参数传递给 process 方法
}
super 关键字:
super
通常在子类中使用,用于访问父类(超类)的成员,包括属性、方法和构造器。super()
用于调用父类的构造器:class Child extends Parent {
public Child() {
super(); // 调用父类无参构造器
}
public Child(String name) {
super(name); // 如果父类有一个接受 String 参数的构造器,则调用该构造器
}
}
super
用于调用父类被覆盖(重写)的方法:class Animal {
public void makeSound() {
System.out.println("动物发出叫声");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
super.makeSound(); // 调用父类的 makeSound 方法
System.out.println("狗叫汪汪汪");
}
}
super
也可以用于访问父类中被隐藏的静态字段。