继承
为什么要继承?首先Java中使用类对现实世界中实体来进行描述,类经过实例化之后的产物对象,可以用来表示现实中的实体,但是这些实体是否有共同特点呢?答案是有的。那既然是共同特点,是否就有重复的代码呢?答案是有的,答案是有的。那为了代码的简洁性来说,便出现了继承。
请看下面的代码:狗(dog)类
public class Dog{
string name;
int age;
float weight;
public void eat(){
System.out.println(name + "正在吃饭");
}
public void sleep(){
System.out.println(name + "正在睡觉");
}
void Bark(){
System.out.println(name + "汪汪汪~~~");
}
}
猫(cat)类
public class Cat{
string name;
int age;
float weight;
public void eat(){
System.out.println(name + "正在吃饭");
}
public void sleep(){
System.out.println(name + "正在睡觉");
}
void mew(){
System.out.println(name + "喵喵喵~~~");
}
}
两者都有共同的属性,name,age,weight,因此为了避免代码的重复,我们可以提取出一个animal类。所以我们将这些共性进行抽取,如下。
public class Animal{
string name;
int age;
float weight;
public void eat(){
System.out.println(name + "正在吃饭");
}
public void sleep(){
System.out.println(name + "正在睡觉");
}
}
继承的概念
继承的语法
需要有extends关键字,如下
修饰符 class 子类 extends 父类 {
// ...
}
所以上述的dog类就可以写成如下形式
public class Dog extends Animal(){
void Bark(){
System.out.println(name + "汪汪汪~~~");
}
}
注意:
当创建一个子类对象的时候,并不会额外创建一个父类的对象,而是父类作为子类对象的一部分,子类对象内部有指向父类的引用,通过这个引用可以访问父类的成员。
子类应当由父类没有的成员变量或者成员方法,否则就不需要继承了
而这个引用就是依靠super关键字。(后续讲解)
父类成员访问
成员变量
1.父类和子类没有存在同名的成员变量
规则:子类有的访问子类,父类有的访问父类;
2.父类和子类存在同名的成员变量
规则:如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
读者可以自己尝试写几个代码。
成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找。
成员方法
1.成员方法名字不同
super关键字
public class Base{
public void methodA(){
System.out.println("Base中的methodA()");
}
public void methodB(){
System.out.println("Base中的methodB()");
}
}
public class Derived extends Base{
// 与父类中methodA()构成重载
public void methodA(int a) {
System.out.println("Derived中的method()方法");
}
// 与基类中methodB()构成重写(即原型一致,重写后序详细介绍)
public void methodB(){
System.out.println("Derived中的methodB()方法");
}
public void methodC(){
// 父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法
methodA(); // 没有传参,访问父类中的methodA()
methodA(20); // 传递int参数,访问子类中的methodA(int)
// 如果在子类中要访问重写的基类方法,则需要借助super关键字
methodB(); // 直接访问,则永远访问到的都是子类中的methodA(),基类的无法访问到
super.methodB(); // 访问基类的methodB()
}
}
重写和重载的辨析在后面部分
在methodc类中,如果我们要访问父类的methodB(),则需要用super.methodB();来访问,如果是要访问子类自己的,那么只需要写methodB();就行,等价于this.methodB();
访问父类的成员变量
例如上面的父类为Aniaml和子类Dog:
public class Animal{
string name;
int age;
float weight;
public void eat(){
System.out.println(name + "正在吃饭");
}
public void sleep(){
System.out.println(name + "正在睡觉");
}
}
这边因为父类再没有创建构造方法的时候,会默认存在一个构造方法,而子类没有写super时,则会默认存在一个super();所以这种情况下编译器不会报错
public class Dog extends Animal(){
void Bark(){
System.out.println(name + "汪汪汪~~~");
}
}
但是如果父类写了带参数的构造方法:
public Animal(string name, int age, float weight){
this.name =name;
this.age = age;
this.weight = weight;
}
则字类中需要存在带3个参数(即相同参数)的super
public class Dog extends Animal(){
super(name,age,weight);
void Bark(){
System.out.println(name + "汪汪汪~~~");
}
}
注意:
一、super不能用在静态方法中(即不能有static修饰);
二、子类的权限不可以比父类的权限来的大(可以记忆成:老子比儿子厉害)
如果父类为public,那么子类为public,包访问权限(default),protected,private都可以
但是如果父类为default,那么子类只能为包访问权限(default),protected,private,以此类推。
上面涉及到了重载和重写,
不得不用一个小篇幅来帮助读者区分:大致如下:
在Java中,重写(Override)和重载(Overload)是两个不同的概念,它们在多态性的实现中扮演着重要的角色。
重写(Override)
重写是指子类有一个方法,这个方法的签名(包括方法名和参数列表)与父类中的某个方法的签名完全相同。通过重写,子类能够提供一个特定的实现,这个实现将会覆盖父类中的方法。
- 重写发生在两个类之间,父类和子类之间。
- 方法名称和参数列表必须与父类方法完全相同。
- 返回类型必须相同或是父类返回类型的子类(称为协变返回类型),如下:
class Fruit {
public Fruit getFruit() {
return new Fruit();
}
}
class Apple extends Fruit {
@Override
public Apple getFruit() {
return new Apple();
}
}
在这个例子中,Fruit
类有一个 getFruit
方法,返回一个 Fruit
对象。Apple
类继承自 Fruit
,并重写了 getFruit
方法,但这里它返回了一个 Apple
对象,而 Apple
是 Fruit
的子类。这就是协变返回类型的应用。
- 访问权限不能比父类中被重写的方法更严格。
- 重写的方法可以抛出与原方法相同的异常或其子异常,但不能抛出更广泛的异常。(暂且不考虑异常这个知识点)
- 使用
@Override
注释可以帮助确保你正确地重写了父类方法。
重载(Overload)
重载是指在同一个类中,有多个同名方法,但它们的参数列表不同(参数的数量不同、参数类型不同或参数的顺序不同)。
- 重载发生在同一个类中,或者在子类中(子类可以重载继承自父类的方法)。
- 方法名称相同,但参数列表必须不同。
- 返回类型可以相同,也可以不同,并不影响重载。
- 访问权限没有特殊要求。
- 可以抛出不同的异常。(暂且不考虑异常这个知识点)
class Animal {
void sound() {
System.out.println("Some sound");
}
}
class Dog extends Animal {
// 这是一个重写
@Override
void sound() {
System.out.println("Woof");
}
// 这是一个重载
void sound(int times) {
for (int i = 0; i < times; i++) {
System.out.println("Woof");
}
}
}
总结:重写是子类对父类方法的具体实现,参数列表和返回值都需相同。重载是在同一个类中创建多个方法名相同但参数列表不同(也可相同),返回值不同(也可相同)的方法。
super和this
接下来在来区分这一组关键字,
继承关系的执行顺序
一、在没有继承代码时。执行的顺序是:
继承方式
注意Java中不支持多继承
在多层继承的情况下,最底层的类可以继承此类往上的所有类的成员变量和成员方法(只要不是私有的)而不是只能继承到父类的
final 关键字
final关键可以用来修饰变量、成员方法以及类。
感谢您耐心阅读这篇关于Java继承的文章!如果这些内容对您有所启发,或者您有更多的见解和疑问,欢迎在下方评论区留言分享您的想法。交流和讨论可以帮助我们共同进步!
如果您喜欢这篇文章,请不要吝啬您的点赞👍,您的每一个赞都是对我写作的最大鼓励。同时,您可以收藏🌟这篇博客,方便日后查阅或与朋友分享。
再次感谢您的阅读与支持!期待在评论区与您的精彩互动!💬