1.为什么需要继承
在编程中,继承可以实现代码的复用,减少重复编写代码的工作量。通过继承,子类可以继承父类的属性和方法,并且可以根据需要进行扩展和修改,提高了代码的可维护性和可扩展性。再例如现实世界的复杂性,但事物之间存在某种共性,那么程序设计就需要考虑
例如
代码语言:javascript复制public class test1 {
public static void main(String[] args) {
Dog dog=new Dog();
dog.eat();
dog.run();
Cat cat=new Cat();
cat.eat();
cat.sleep();
}
}
class Dog{
public void eat(){
System.out.println("吃饭");
}
public void run(){
System.out.println("狗狗正在跑");
}
}
class Cat{
public void eat(){
System.out.println("吃饭");
}
public void sleep(){
System.out.println("猫猫正在睡觉");
}
}
在狗和猫之间有共性即吃饭,如果共性很多时候,我们每个类都要加入对应的方法,所以我们就可以设置一个类来存储共性,让猫和狗继承它就会使的代码更简便。
2.继承的概念
继承允许创建一个新的类(称为子类或派生类),它允许保持原有的特性的基础上进行扩展,增加新功能。该类基于另一个已存在的类(称为父类、基类或超类)。子类继承了父类的属性(数据成员)和方法(成员函数)。这意味着子类无需重新定义父类中已有的属性和方法,就可以直接使用它们。解决问题:共性的抽取,实现代码复用。
3.继承的语法
如果子类要继承父类,那么就要加关键词extends。
代码如下:
代码语言:javascript复制class Animal{
public void eat(){
System.out.println("吃饭");
}
}
class Dog extends Animal{
public void run(){
System.out.println("狗狗正在跑");
}
}
当将共性写在父类时,代码就显得更加简洁。
注意:如果子类继承父类之后,不添加自己的特有成员(成员变量,成员方法),与基类相同,就没有必要继承了。
4.成员访问
1.子类与父类不存在同名的时候:在子类中可以使用父类指定的成员,或者自己的。
代码如下:
代码语言:javascript复制class son extends father{
int a;
public void sum(){
a=1;
b=2;
}
}
class father{
int b;
}
子类没有b的变量,但是继承后就任然使用。
2.子类与父类的成员同名的时候:如果访问的变量在子类中存在,就访问子类的成员变量,如果没有,就在父类里面找,如果还是没有编译器就报错。
代码语言:javascript复制 public static void main(String[] args) {
son s=new son();
System.out.println(s.b);
s.a();
}
}
class son extends father{
String b="这是子类的成员变量";
public void a(){
System.out.println("这是子类的成员方法");
}
}
class father{
String b="这是父类的成员变量";
public void a(){
System.out.println("这是父类的成员方法");
}
}
代码输出:这是子类的成员变量 这是子类的成员方法
5.super关键字
在上述中代码中,当子类与父类的成员变量,或者成员方法名一样时,如何使用父类的呢?
这里就要用super关键字。
super关键字的作用:在子类或者父类存在成员名相同时,可以使用super在子类中访问父类的成员变量,或者成员方法。
代码语言:javascript复制class son extends father{
String b="这是子类的成员变量";
public void a(){
System.out.println("这是子类的成员方法");
}
public void b(){
System.out.println(super.b);
super.a();
}
}
class father{
String b="这是父类的成员变量";
public void a(){
System.out.println("这是父类的成员方法");
}
}
输出结果:这是子类的成员变量 这是子类的成员方法 这是父类的成员变量 这是父类的成员方法
注意:super只能在非静态方法中使用。
6.子类构造方法
子类对象构造时,先调用父类的构造方法,在执行子类的构造方
代码语言:javascript复制public class test3 {
public static void main(String[] args) {
Son son=new Son();
}
}
class Son extends Father{
public Son(){
System.out.println("子类的构造方法");
}
}
class Father{
public Father(){
System.out.println("父类的构造方法");
}
}
输出结果: 父类的构造方法 子类的构造方法
在子类构造方法中没有写父类的构造的代码,但是在构造子类的对象时,会自动执行父类的构造方法,然后执行子类的构造方法。
注意:
1.在父类构造默认或者无参的构造方法的时候,在子类的构造方法的第一行会默认加super().
2.如果父类时带有参数的构造函数,那么子类需要显示定义构造方法。
代码语言:javascript复制public class test4 {
public static void main(String[] args) {
Sub sub = new Sub(2,3);
System.out.println(sub.calculate());
}
}
class Base {
private int x;
public Base(int x) {
this.x = x;
}
public int getX() {
return x;
}
}
class Sub extends Base {
private int z;
public Sub(int x, int z) {
super(x);
this.z = z;
}
public int calculate() {
return super.getX()*z;
}
}
7.super和this
相同:
都只能在非静态方法中使用,用来访问非静态成员防范和变量。
必须是构造方法中的第一条语句,并且不能同时存在。
不同点:
this是当前对象的引用,super是子类对象中对父类继承下来的引用。
this用来访问本类的方法和属性,super是访问的是父类继承下来的方法和属性。
在构造方法中,this用于调用本类的构造方法,super用来调用父类的构造方法,且两者不能同时出现构造方法中。
8.再谈初始化
静态代码块先执行,并且只执行一次,在类加载阶段执行。
当对象创建时,才执行实例代码块,实例代码块执行完成后才执行构造方法。
代码语言:javascript复制public class test3 {
public static void main(String[] args) {
testDemo t=new testDemo();
System.out.println("----------------");
testDemo t1=new testDemo();
}
}
class testDemo{
public testDemo(){
System.out.println("这是构造方法");
}
{
System.out.println("这是实例代码块");
}
static {
System.out.println("这是静态代码块");
}
}
输出: 这是静态代码块 这是实例代码块 这是构造方法 ---------------- 这是实例代码块 这是构造方法
如图所示,静态代码块执行完一次后就不执行了。
并且存在子类继承父类时,父类的静态代码块最先执行,然后是子类的静态代码块,父类的实例代码块和构造方法再执行,最后是子类的实例代码块和构造方法。
9.protect关键字
protect关键字可用于,同一包中的同一类和不同类,以及不同包中的子类。
如图所示,protect只能用于同一包中,和不同包中的子类,由于小编在这里无法展示,不同包的情况,请见谅。
10.继承方式
单继承:
class A<------class B
多层继承:
class A<------class B<-----class C
不同类继承同一个类:
class A<------class B class A<------class C
多继承
class A<------class B class C<------class B(注意:在java中不支持多继承)
11.final关键字
1. 修饰变量: 当 final 修饰基本数据类型的变量时,该变量的值一旦被初始化就不能被修改。 当 final 修饰引用数据类型的变量时,该变量所引用的对象地址不能被改变,但对象的内容可以改变。 2. 修饰方法: 被 final 修饰的方法不能被重写,这确保了方法在继承体系中的行为是固定的。 3. 修饰类: 被 final 修饰的类不能被继承,意味着这个类的功能是完整且不可扩展的。
在修饰变量时:
final int a=10; a=20;//编译报错
在修饰时类时:
final class A{ } class B extends A{} //编译报错,
final修饰类时,表示该类不应被继承;
在修饰方法时:
代码语言:javascript复制class A extends B{
public void func(){
//报错,不能被重写。
}
}
class B{
public final void func(){
}
}
该方法不能被重写;
12.总结
限于小编能力有限,可能总结不是很到位,希望各位uu给出宝贵意见。
如果觉得小编写的还不错的话,麻烦给小编一个小小的赞吧