网站编辑合适内向的人做吗,凡客网站的域名怎么做,网站顶部flash,大牌装修公司记录学习Java基础中有关继承、方法重写、构造器调用的基础知识#xff0c;学习继承之前建议学习static关键字的内容【自学笔记】01Java基础-09Java关键字详解
1 继承概述
1.1 什么是继承#xff1f; 1.2 继承的特点
子类可以继承父类的属性和行为#xff0c;但是子类不能…记录学习Java基础中有关继承、方法重写、构造器调用的基础知识学习继承之前建议学习static关键字的内容【自学笔记】01Java基础-09Java关键字详解
1 继承概述
1.1 什么是继承 1.2 继承的特点
子类可以继承父类的属性和行为但是子类不能继承父类的构造器。Java是单继承模式一个类只能继承一个直接父类。Java不支持多继承、但是支持多层继承。Java中所有的类都是Object类的子类。
1.3 继承的重要问题
1.3.1 子类是否可以继承父类的构造器
不可以的子类有自己的构造器父类构造器用于初始化父类对象。
1.3.2 子类是否可以继承父类的私有成员方法变量
可以的只是不能直接访问。 具体表现如下
子类不能直接引用父类的私有字段成员变量。子类不能覆盖override父类的私有方法。子类可以通过调用父类提供的公共public或受保护protected方法来间接访问或者修改私有字段的值前提是父类提供了这样的接口。
例如在父类中有一个私有变量并且提供了一个公共的getter和setter方法那么子类就可以通过调用这些方法来读取和设置该私有变量的值。
1.3.3 子类是否可以继承父类的静态成员
有争议的知识点。 子类可以直接使用父类的静态成员共享 但个人认为子类不能继承父类的静态成员。共享并非继承
Java中静态成员包括静态变量和静态方法是与类关联的而不是与对象实例关联。因此子类可以直接访问父类的静态成员但不会重新创建或覆盖这些成员。
public class Parent {public static int count 0;// 静态方法public static void incrementCount() {count;}
}public class Child extends Parent {// 子类无需定义count直接可以使用Parent.countpublic static void main(String[] args) {// 直接通过类名访问父类的静态成员System.out.println(Parent.count); // 输出0Parent.incrementCount();System.out.println(Parent.count); // 输出1System.out.println(Child.count); // 输出1因为Child和Parent共享同一个静态变量count}
}在这个例子中Child 类和 Parent 类共享同一个 count 变量。同样Child 类也可以调用 Parent 中的public静态方法 incrementCount()。但是子类不能重写父类的静态方法只能重新声明一个同名的静态方法这将被视为一个新的方法而非覆盖。
1.4 继承后方法、变量的访问优先级
满足就近原则。
先子类局部范围找然后子类成员范围找然后父类成员范围找如果父类范围还没有找到则报错。
当子类中方法或变量与父类重名时会优先使用子类的此时如何指定使用父类的方法或变量 可以通过super.父类成员变量/父类成员方法指定访问父类的成员。了解super关键字
1.5 子类如何声明与父类同名的变量的两种方式
子类中想声明与父类同名的变量时有两种情况
对于父类中static修饰的静态变量类变量子类必须声明为static类型。子类和父类的static同名变量各自独立前面学过了子类中使用父类中static变量直接类名.变量可以查看了解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); // 输出10System.out.println(Child.count); // 输出20}
}对于父类中非static修饰的实例变量子类可以声明与父类同名的非static变量可以使用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}
}2 方法重写 public class Animal {public void makeSound() {System.out.println(动物发出叫声);}
}public class Dog extends Animal {Override // 标注此方法是重写父类Animal的makeSound方法public void makeSound() {System.out.println(狗叫汪汪汪);}
}2.1 Override重写注解的作用
在上方示例代码中重写的方法makeSound()上方出现了Override注解。
Override注解放在重写后的方法上作为重写是否正确的校验注解。加上该注解后如果重写错误编译阶段会出现错误提示。建议重写方法都加Override注解代码安全优雅也并非一定要加。
2.2 方法重写的注意事项
子类必须继承自父类。重写方法的名称、形参列表、返回类型必须与被重写方法的一致。private私有方法和static静态方法不能被重写。子类重写父类方法时访问权限必须大于或者等于父类 权限范围缺省 protected public重写的方法抛出的异常类型不能大于父类对应方法允许抛出的异常类型也就是说子类重写的方法可以不抛出异常或者抛出父类方法所声明异常的子类异常。
3 子类构造器
复习构造器的概念 封装-构造方法
子类并不继承父类的构造器而是在自己构造器调用父类构造器来初始化从父类继承而来的成员变量。
子类可以通过 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;}
}3.1 子类构造器调用父类有哪些情况 前言 我们知道在实体类中没有定义任何构造器时系统会自动提供一个默认无参构造器。 一旦定义了至少一个构造器无论是否有参数Java编译器将不再自动提供无参构造器。这时若需无参构造器来创建对象那么必须手动提供一个无参构造器否则将会报错。 所以子类构造器调用父类有以下情况
父类没有显式定义任何构造器此时默认有无参构造器子类会默认隐式调用父类无参构造器父类显式定义了无参构造器此时子类会默认隐式调用父类无参构造器。父类显式定义了有参构造器此时子类必须显式调用super(...)至少一个有参构造器否则因为无法找到默认无参构造器报错。父类显式定义了有参构造器和无参构造器此时子类会默认隐式调用无参构造器也可以显式调用任一构造器。
3.2 子类为什么必须调用父类构造器
子类在初始化的时候有可能会使用到父类中的数据如果父类没有完成初始化子类将无法使用父类的数据。子类初始化之前一定要调用父类构造器先完成父类数据空间的初始化。
4 this和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 {Overridepublic void makeSound() {super.makeSound(); // 调用父类的 makeSound 方法System.out.println(狗叫汪汪汪);}
}同样super 也可以用于访问父类中被隐藏的静态字段。