网站点,苏州营销型网站开发公司,百度地图导航下载安装,产品开发流程ppt继承 继承为什么使用继承继承是什么继承的语法访问父类成员访问父类成员变量访问父类成员方法 super关键字子类构造方法super和this异同分别的使用方法 继承的方式final关键字 作者简介#xff1a; zoro-1#xff0c;目前大一#xff0c;正在学习Java#xff0c;数据结构等… 继承 继承为什么使用继承继承是什么继承的语法访问父类成员访问父类成员变量访问父类成员方法 super关键字子类构造方法super和this异同分别的使用方法 继承的方式final关键字 作者简介 zoro-1目前大一正在学习Java数据结构等 作者主页 zoro-1的主页 欢迎大家点赞 收藏 ⭐ 加关注哦 继承
为什么使用继承
Java中使用类对现实世界中实体来进行描述类经过实例化之后的产物对象则可以用来表示现实中的实体但是 现实世界错综复杂事物之间可能会存在一些关联那在设计程序是就需要考虑。
比如猫和狗我们分别用一个类来表示 狗类
// Dog.javapublic 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.Javapublic 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 喵喵喵~~~);}
}他们类中会有很多相同的属性就造成了代码冗杂 面向对象思想中提出了继承的概念专门用来进行共性抽取实现代码复用。
继承是什么
共性的抽取实现代码复用
上述图示中Dog和Cat都继承了Animal类其中Animal类称为父类/基类或超类Dog和Cat可以称为Animal的子类/派生类继承之后子类可以复用父类中成员子类在实现时只需关心自己新增加的成员即可。
继承的语法
在Java中如果要表示类之间的继承关系需要借助extends关键字具体如下
修饰符 class 子类 extends 父类 {// ... }// Animal.javapublic class Animal{String name;int age;public void eat(){System.out.println(name 正在吃饭);}public void sleep(){System.out.println(name 正在睡觉);}
}// Dog.javapublic class Dog extends Animal{ void bark(){System.out.println(name 汪汪汪~~~);}
}
// Cat.Javapublic class Cat extends Animal{ void mew(){System.out.println(name 喵喵喵~~~);}
}// TestExtend.javapublic class TestExtend {public static void main(String[] args) {Dog dog new Dog();// dog类中并没有定义任何成员变量name和age属性肯定是从父类Animal中继承下来的System.out.println(dog.name);System.out.println(dog.age);// dog访问的eat()和sleep()方法也是从Animal中继承下来的dog.eat();dog.sleep();dog.bark();}
}注意 子类会将父类中的成员变量或者成员方法继承到子类中了 子类继承父类之后必须要新添加自己特有的成员体现出与基类的不同否则就没有必要继承了
访问父类成员
访问父类成员变量
成员变量名字不同
public class Base {int a;int b;
}public class Derived extends Base{int c;public void method(){a 10; // 访问从父类中继承下来的ab 20; // 访问从父类中继承下来的bc 30; // 访问子类自己的c}
}成员变量名字相同
public class Base {int a;int b;int c;
}/public class Derived extends Base{int a; // 与父类中成员a同名且类型相同char b; // 与父类中成员b同名但类型不同public void method(){a 100; // 访问父类继承的a还是子类自己新增的ab 101; // 访问父类继承的b还是子类自己新增的b?c 102; // 子类没有c访问的肯定是从父类继承下来的c// d 103; // 编译失败因为父类和子类都没有定义成员变量b}
}在子类方法中 或者 通过子类对象访问成员时
如果访问的成员变量子类中有优先访问自己的成员变量。如果访问的成员变量子类中无则访问父类继承下来的如果父类也没有定义则编译报错。如果访问的成员变量与父类中成员变量同名则优先访问自己的。
成员变量访问遵循就近原则自己有优先自己的如果没有则向父类中找。
访问父类成员方法
成员方法名字不同
public class Base {public void methodA(){System.out.println(Base中的methodA());}
}public class Derived extends Base{public void methodB(){System.out.println(Derived中的methodB()方法);}public void methodC(){methodB(); // 访问子类自己的methodB()methodA(); // 访问父类继承的methodA()// methodD(); // 编译失败在整个继承体系中没有发现方法methodD()}
}成员方法名字相同
public class Base {public void methodA(){System.out.println(Base中的methodA());}public void methodB(){System.out.println(Base中的methodB());}
}public class Derived extends Base{public void methodA(int a) {System.out.println(Derived中的method(int)方法);}public void methodB(){System.out.println(Derived中的methodB()方法);}public void methodC(){methodA(); // 没有传参访问父类中的methodA()methodA(20); // 传递int参数访问子类中的methodA(int)methodB(); // 直接访问则永远访问到的都是子类中的methodB()基类的无法访问到}
}通过子类对象访问父类与子类中不同名方法时优先在子类中找找到则访问否则在父类中找找到则访问否则编译报错。通过派生类对象访问父类与子类同名方法时如果父类和子类同名方法的参数列表不同(重载)根据调用方法适传递的参数选择合适的方法访问如果没有则报错
问题如果子类中存在与父类中相同的成员时那如何在子类中访问父类相同名称的成员呢
super关键字
由于设计不好或者因场景需要子类和父类中可能会存在相同名称的成员如果要在子类方法中访问父类同名成员时该如何操作直接访问是无法做到的Java提供了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{public void methodA(int a) {System.out.println(Derived中的method(int)方法);}public void methodB(){System.out.println(Derived中的methodB()方法);}public void methodC(){methodA(); // 没有传参访问父类中的methodA()methodA(20); // 传递int参数访问子类中的methodA(int)methodB(); // 直接访问则永远访问到的都是子类中的methodB()基类的无法访问到}
}public class Base {int a;int b;public void methodA(){System.out.println(Base中的methodA());}public void methodB(){System.out.println(Base中的methodB());}
}
public class Derived extends Base{int a; // 与父类中成员变量同名且类型相同char b; // 与父类中成员变量同名但类型不同// 与父类中methodA()构成重载public void methodA(int a) {System.out.println(Derived中的method()方法);}// 与基类中methodB()构成重写(即原型一致重写后序详细介绍)public void methodB(){System.out.println(Derived中的methodB()方法);}public void methodC(){// 对于同名的成员变量直接访问时访问的都是子类的a 100; // 等价于 this.a 100;b 101; // 等价于 this.b 101;// 注意this是当前对象的引用// 访问父类的成员变量时需要借助super关键字// super是获取到子类对象中从基类继承下来的部分super.a 200;super.b 201;// 父类和子类中构成重载的方法直接可以通过参数列表区分清访问父类还是子类方法methodA(); // 没有传参访问父类中的methodA()methodA(20); // 传递int参数访问子类中的methodA(int)// 如果在子类中要访问重写的基类方法则需要借助super关键字methodB(); // 直接访问则永远访问到的都是子类中的methodA()基类的无法访问到super.methodB(); // 访问基类的methodB()}
}在子类方法中如果想要明确访问父类中成员时借助super关键字即可。
子类构造方法
public class Base {public Base(){System.out.println(Base());}}public class Derived extends Base{public Derived(){// super(); // 注意子类构造方法中默认会调用基类的无参构造方法super(),// 用户没有写时,编译器会自动添加而且super()必须是子类构造方法中第一条语句// 并且只能出现一次System.out.println(Derived());}
}public class Test {public static void main(String[] args) {Derived d new Derived();}
}结果打印Base()Derived()在子类构造方法中并没有写任何关于基类构造的代码但是在构造子类对象时先执行基类的构造方法然后执行子类的构造方法因为子类对象中成员是有两部分组成的基类继承下来的以及子类新增加的部分 。父子父子肯定是先有父再有子所以在构造子类对象时候 先要调用基类的构造方法将从基类继承下来的成员构造完整然后再调用子类自己的构造方法将子类自己新增加的成员初始化完整 。 注意 若父类显式定义无参或者默认的构造方法在子类构造方法第一行默认有隐含的super()调用即调用基类构 造方法 如果父类构造方法是带有参数的此时需要用户为子类显式定义构造方法并在子类构造方法中选择合适的 父类构造方法调用否则编译失败。 在子类构造方法中super(…)调用父类构造时必须是子类构造函数中第一条语句。 super(…)只能在子类构造方法中出现一次并且不能和this同时出现
super和this
异同
【相同点】 都是Java中的关键字 只能在类的非静态方法中使用用来访问非静态成员方法和字段 在构造方法中调用时必须是构造方法中的第一条语句并且不能同时存在
【不同点】 this是当前对象的引用当前对象即调用实例方法的对象super相当于是子类对象中从父类继承下来部分成员的引用 在非静态成员方法中非静态方法参数列表有thisthis用来访问本类的方法和属性super用来访问父类继承下来的方法和属性 在构造方法中this(…)用于调用本类构造方法super(…)用于调用父类构造方法两种调用不能同时在构造方法中出现 构造方法中一定会存在super(…)的调用用户没有写编译器也会增加但是this(…)用户不写则没有
分别的使用方法 继承的方式 时刻牢记, 我们写的类是现实事物的抽象. 而我们真正在公司中所遇到的项目往往业务比较复杂, 可能会涉及到一系列复杂的概念, 都需要我们使用代码来表示, 所以我们真实项目中所写的类也会有很多. 类之间的关系也会更加复杂.但是即使如此, 我们并不希望类之间的继承层次太复杂. 一般我们不希望出现超过三层的继承关系. 如果继承层次太多, 就需要考虑对代码进行重构了. 如果想从语法上进行限制继承, 就可以使用 final 关键字 final关键字
final是Java中的一个关键字用于修饰类、方法和变量具体作用如下
final修饰的类无法被继承final修饰的方法无法被子类重写final修饰的变量为常量值不可改变final修饰的引用变量其引用地址不可改变但是其所引用的对象的状态可以改变。
使用final关键字可以增强代码的安全性和可读性避免一些不必要的错误操作。