首页 > 其他分享 >继承extends

继承extends

时间:2022-10-19 07:22:05浏览次数:56  
标签:无参 继承 子类 Demo1 extends 父类 super public

继承extends

关键字extends,语法:

public class 子类名 extends 父类{
    
}

子类继承了父类的成员(排除private修饰成员,以及父类的构造方法
子类也叫派生类,父类也叫基类。java里面的继承属于单根继承,一个类只能继承一个类,所有的类都默认继承超级父类Object。子类可以有独有的成员变量和方法。

创建子类对象
1. 默认执行父类的无参构造
2. 执行子类的无参构造

创建子类对象的时候,先输出父类的无参构造,再输出子类的构造,如果在父类有static代码块时候,先走静态代码块,因为static是class加载的时候就被加载,所以在子类对象被创建的时候,先走父类的静态代码块,再走子类的静态代码块,再回到栈内存创建子类的对象,再走父类的无参构造,再走子类的无参构造

子类 对象名=new 子类();
//执行流程:父类class被加载-->父类静态代码块被加载-->子类class被加载-->子类static被加载-->父类构造-->子类构造

且子类需要通过set/get来访问父类继承到的私有属性

demo1.setId(3);//给继承父类的id属性赋值
demo1.getId();//得到id

创建子类对象默认调用了父类的无参构造方法,但没有创建父类对象,因为没有new在堆内存开辟空间

public class Demo {
    private int id;
    public Demo() {
        System.out.println("父类的无参构造this"+this);
    }
    static {
        System.out.println("父类的staic代码块");
    }
}
public class Demo1 extends Demo {
    public Demo1() {
        //默认调用了父类的无参构造,也就是默认存在super();
        System.out.println("子类的无参构造this"+this);
    }
    static {
        System.out.println("子类的staic代码块");
    }
}

子类的所有构造方法里面默认调用了父类的无参构造,也就是默认存在super();,所以会先走super();执行父类的无参构造,再走子类构造的内容。

public static void main(String[] args) {
    Demo1 demo1 = new Demo1();
        demo1.setId(3);
        System.out.println(demo1.getId());
        System.out.println("创建的对象demo1"+demo1);
}

输出结果是

父类的staic代码块
子类的staic代码块
父类的无参构造thiscom.extendsdemo.Demo1@1540e19d
子类的无参构造thiscom.extendsdemo.Demo1@1540e19d
3
创建的对象demo1com.extendsdemo.Demo1@1540e19d

表示在继承关系下创建的子类对象,在父类中的this还是正在执行的对象,也就是子类对象。

子类代码:

public class Demo1 extends Demo {
    private String name;
    public Demo1() {
        System.out.println("子类的无参构造this"+this);
    }
    public Demo1(String name,int id) {
     //默认存在super();执行调用父类的无参构造
        this.name=name;
        this.setId(id);
    }

}

父类代码:

public class Demo {
    private int id;
    public Demo(int id) {
        this.id = id;
    }
    public Demo() {
        System.out.println("父类的无参构造this"+this);
    }
}

执行程序类:

public class test1 {
    public static void main(String[] args) {
        Demo1 demo1 = new Demo1("张三",36);
        System.out.println(demo1.getId());
        System.out.println(demo1.getName());
    }
}

输出结果:

父类的无参构造thiscom.extendsdemo.Demo1@1540e19d
36
张三

这时候假如我把父类的无参构造删掉留下父类的有参构造,会出现什么现象?

Error:(16, 20) java: 无法将类 com.extendsdemo.Demo中的构造器 Demo应用到给定类型;
  需要: int
  找到: 没有参数
  原因: 实际参数列表和形式参数列表长度不同

在子类的无参构造中调用父类的有参构造是没有意义的,所以正常开发中,几乎不存在子类的无参或少参数的构造调用父类的有参,子类的有参构造也不会调用父类的无参构造,因为子类的有参构造是用来赋值的,如果调用父类的无参,子类的有参构造的参数就没有赋到值,不会混合使用,也就是有参调有参,无参调无参。

当父类中没有无参构造方法时,子类需要加上super(参数);

public class Demo1 extends Demo {
    private String name;
    public Demo1() {
        super(28);//需要赋值,因为子类没有参数给传值
        System.out.println("子类的无参构造this"+this);
    }
    public Demo1(String name){
        super(36);;//需要赋值,因为子类没有参数给传值
    }
    public Demo1(String name,int id1) {
        super(id1);//不需要赋值,这里有参数id1来传递参数给父类的有参构造
        this.name=name;
//        this.setId(id);父类无参构造删掉时候需要用super(id)代替这行操作
    }

所以说,如果父类改变的时候子类也需要改变,是比较麻烦的,这时候可以利用工具来完成alt+ctrl,选中所有的构造方法,就可以完成子类的构造创建。

super

this和super的区别:

this是指当前执行的对象,可以调用属性和方法。

super只是一个父类引用的关键字,不是对象,假如把父类的无参构造删掉,需要加上super(子类继承的属性赋值)。

1. 在子类中,super可以访问父类成员变量和方法
子类属性跟父类属性相同时候,利用super来区分子类和父类的属性
父类代码:
public class Demo {
    private int id=100;
    public Demo() {
    }
}
子类代码:
public class Demo1 extends Demo {
    private int id=34;
    public Demo1() {
      super();//调用父类的无参构造,因为父类在这时没写有参,所以我这里子类也不写有参构造
    }
    public void fun(){
        System.out.println("子类的id"+this.id);//34
        System.out.println("父类的id"+super.getId());//100
    }
   /* public static void main(String[] args) {//执行程序
        Demo1 demo1=new Demo1();
        demo1.fun();
    }*/
}
所以在子类和父类的属性定义名称时最好不要定义相同的,如果相同需要用super区分
2. 在子类构造中,利用super调用父类构造方法
方法重写

方法重载:方法名相同,形参不同,与修饰符和返回值无关。一般体现在工具类

方法重写:前提:有层级关系(继承,实现)

在子类中重写父类的方法

方法名和形参必须与父类的方法相同

父类代码:

@Setter
@Getter
public class Demo {
    private int id=100;
    public Demo() {
    }
    public void fun(){
        System.out.println("父类的方法");
    }
}

子类方法重写:alt+ctrl选择override

public class Demo1 extends Demo {
    private int id=34;
    public Demo1() {
      super();
    }
    @Override//jdk提供的内置注解
    public void fun(){//对父类的方法重写
        super.fun();//加上这一行父类的方法也会执行,如果不加这一行父类的fun不会执行
        System.out.println(getId()+"对父类的方法重写");
    }
}
举例:重写超级父类object类的tostring方法

需要在父类代码中重写tostring方法:

public class Demo {
    private int id=100;
    public Demo() {
    }
    @Override
    public String toString() {
        return "Demo{" +
                "id=" + id +
                '}';
    }
}

子类代码中的tostring会返回super.toString();因为他的父类是Demo,而Demo的父类才是object类,所以子类继承之前需要在父类中先重写超级父类中的方法:

public class Demo1 extends Demo {
    private int id=34;
    public Demo1() {
      super();
    }
    @Override
    public String toString() {
        return super.toString();
    }
}

在main中就可以直接将子类对象转换成字符串打印出来:

public static void main(String[] args) {
    Demo1 demo1=new Demo1();
    System.out.println(demo1.toString());
}

输出结果:

Demo{id=100}
子返回值类型要小于等于父类方法的返回值,访问权限修饰符要大于等于父类的访问权限修饰符

如果一个数据类型底层代码是final修饰,说明它是没有子类的。public>protected>默认>private 所以一般父类可以写成protected,可以只对子类友好。

父类方法用object类

private Object fun(){
    return null;
}

那子类重写方法中返回值得小于父类方法的返回值

public String str(){
    return null;
}

但是不推荐在子类中重写父类的方法:

在面向对象编程的设计中:
SOLID:
     S:单一功能原则
     O:开放闭合原则
     L:里氏替换原则
     I:接口隔离原则
     D:依赖注入原则
里氏替换原则:
1. 父类出现的地方都可以使用子类替换
2. 不要随意更改父类结构,如果要重写方法可以用抽象方法/接口替换

标签:无参,继承,子类,Demo1,extends,父类,super,public
From: https://www.cnblogs.com/Liku-java/p/16804859.html

相关文章

  • 继承和多态
    动手实验:继承条件下的构造方法调用运行TestInherits.java示例,观察输出,注意总结父类与子类之间构造方法的调用关系修改Parent构造方法的代码,显式调用GrandParent的另一个......
  • (面向对象)已知定义人的类Person,请完成:1.定义学生的类Stu并继承人的类Person;2.重写构造
    样例输入张三男李四女19 样例输出姓名:张三,性别:男李四女19姓名:王五,性别:?,年龄:29解题代码#coding=gbk#定义人的类classPerson(object):#继承o......
  • java继承
    1.继承的实际是子类继承了父类的方法和属性,我们可以使用super关键字调用父类的方法,或者this关键字调用自己的方法2.在继承的基础上我们可以拥有父类的已好的方法,同时也可......
  • 设计"继承"的目的是什么?
    经常需要扩展现有类型来添加功能(行为和数据)例如,假定已经有Person类,可创建Employee类并在其中添加EmployeeId和Department等员工特有的属性也可以采取相反的操作......
  • 面向对象语言的三大特性:封装,继承,多态
    封装:可以将事物的属性和行为抽象出来,封装在一个类中。继承:子类可以从基类上继承其(全部或部分)属性和函数。多态:多态是指一个接口,对应多种实现。C++的多态性具体体现在编译......
  • [答疑]EA中类怎么表现私有继承
    陈诒亮(875365197)09:29:37EA中类怎么表现私有继承陈诒亮(875365197)09:29:44private继承潘加宇(3504847)22:11:10设置泛化关系的范围为private。这是某些特定编程语言的......
  • Maven:聚合与继承
    转自:https://zhuanlan.zhihu.com/p/139793065Maven不仅支持单模块项目同时还支持多模块项目,这里将介绍在多模块Maven项目中广泛应用的聚合、继承等概念,并就如何通过裁剪反......
  • 在python中如何实现类的继承,方法重载及重写?(原来继承这么简单-附完整代码详解)
    ......
  • 第四讲 继承与多态 课后总结
    什么是继承?继承是对现实生活中的“分类”概念的一种模拟。狮子拥有动物的一切基本特性,但同时又拥有自己的独特的特性,这就是“继承”关系的重要特性:通常简称为“IS_A”关......
  • 41.继承的方式
    程序:#pragmawarning(disable:4996)#define_CRT_SECURE_NO_WARNINGS1//2022年10月15日20:24:40#include<iostream>usingnamespacestd;classFather{public:......