Java基础——继承,我继承了什么

类的继承格式

class 父类 {
}
class 子类 extends 父类 {
}

通过extends关键字来实现

一、为什么需要继承

有一些类有共同的地方,容易出现代码冗余,所以我们需要抽取一下,封装继承多态嘛。

子类通过复写方法等方式可以对父类做一些拓展,比如:
笔都有产地和颜色,笔就是父类,钢笔继承自笔,钢笔的产地和颜色是什么,蜡笔呢,毛笔也有,但是毛笔没有笔帽,特殊一点,这就可以做拓展了,为什么没有笔帽,要注意什么。

二、继承到底继承了什么?有什么特点?

一个类里面有4种东西

  • 属性(包括类属性和实例属性)、
  • 方法(包括类方法和实例方法)、
  • 构造器/构造方法
  • 初始化块(包括类的初始化块和实例的初始化块)。

子类继承父类的时候,到底继承了什么?

  • 1、子类继承父类所有的属性(除了private)
  • 2、子类继承父类(除private)所有的方法,(子类方法如果不调用 super.所复写方法名称 ,那么对应父类方法将不会执行)
    • final方法不可以被继承
    • static方法不可以被继承,随着类的加载而加载,继承毛线。但是如果权限允许子类还是可以用。
  • 3、子类可以通过super,表示父类的引用,调用父类的属性或者方法。
    (构造函数和代码块是无法被继承)

对于private这点非常好理解,因为private的访问权限是本类中嘛,就算通过super也不能访问private的private属性。但是可以通过对应的get方法获取,get是public嘛。

如果子类非要访问父类的私有域,那么就反射吧

继承有什么特点:

  • Java只可以单继承,不能多继承

  • 继承的好处是是可以提高效率,抽取封装,缺点是提高了代码耦合。

  • Object是所有类的直接或者间接父类,Object是万类之祖。

  • 继承中的this和super

    • super关键字
      我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

    • this关键字
      指向自己的引用。

  • 继承与final

    • final 类
      final class 类名 {//类体}

      不能继承的,即最终类
      被声明为 final 类的方法自动地声明为 final,但是实例变量并不是 final

    • final方法
      修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

      该方法不能被子类重写

  • final实例变量

    final修饰的变量称为常量,这些变量只能赋值一次,final 的变量不能被修改
    final修饰的引用类型变量,表示该变量的引用不能变,而不是该变量的值不能变;

  • 如果子类方法签名和父类签名完全一致,那就必须写上@Override的注解,也就是必须复写,不然的话,报错。

  • 调用被覆盖的父类方法:使用super.方法名(实参);

三、子类的初始化

类的初始化分为 类初始化 和 对象初始化。

三、1.类初始化

先执行父类的 类成员(static成员) 和 类代码块(static代码块),后执行子类的类成员(static成员) 和 类代码块(static代码块)。

static成员和static代码块仅会在类加载的时候加载一次。

三、2.对象初始化

1、先初始化父类的属性和代码块,后初始化子类的属性和代码块。
2、接着初始化父类的构造函数,然后是子类

关于子类能从父类继承到什么和继承中的类初始化,我们看一下下面的代码就清楚了:

AClass

public class AClass {
    int normalVar = 10;
    // 父类私有变量,子类无法继承,但可以get到
    private int priVar = 20;
    {
        System.out.println("AClass 普通代码块");
    }
    
    static{
        System.out.println("AClass static代码块");
    }
    
    public AClass(){
        System.out.println("AClass 无参构造方法");
    }
    
    public AClass(String str){
        System.out.println("AClass 带参构造方法!");
        
    }
    public void aMethodOne(){
        normalVar = 55;
        System.out.println("aMethodOne");
    }
    
    public void aMethodTwo(){
        normalVar = 66;
        System.out.println("aMethodTwo");
    }
    
    public int getPriVar() {
        return priVar;
    }
    
    public void setNormalVar(int normalVar) {
        this.normalVar = normalVar;
    }
}

.
.
BClass

public class BClass extends AClass{
    {
        System.out.println("BClass 普通代码块");
    }
    
    static{
        System.out.println("BClass static代码块");
    }
    

    public BClass(){
        System.out.println("BClass 无参构造方法");
    }
    
    public BClass(String str){
        System.out.println("BClass 带参构造方法!");
    }
    
    @Override
    public void aMethodOne() {
        super.aMethodOne();
        System.out.println("子类Override的aMethodOne方法 并且调用super.aMethodOne();");
    }

    @Override
    public void aMethodTwo() {
        //super.aMethodTwo();
        System.out.println("子类Override的aMethodTwo方法 不调用super.aMethodTwo();");
    }
    
    public void getFatherVar(){
        System.out.println("调用父类的非私有变量:"+normalVar);
        //int a = priVar; // 父类的私有变量子类无法继承,本句会报错
    }
}

.
.
TrtExt

public class TrtExt{
    public static void main(String[] args) {
        BClass bClass1 = new BClass();
        
        System.out.println("=========");
        BClass bClassZs = new BClass("张三"); 
        bClassZs.getFatherVar();
        bClassZs.setNormalVar(88); // 子类bClass2对象改变父类的变量,不会影响其他子类
        
        System.out.println("====================");
        BClass bClassLs = new BClass("李四"); 
        bClassLs.getFatherVar();// 
        
        System.out.println("====================");
        BClass bClassWw = new BClass("王五"); 
        bClassWw.getFatherVar();// 父类的原始值
        bClassWw.aMethodOne(); // BClass的aMethodOne方法有super.aMethodOne();所以会调父类的aMethodOne()
        bClassWw.getFatherVar();
        
        System.out.println("====================");
        BClass bClassAl = new BClass("阿六"); 
        bClassAl.getFatherVar();//  父类的原始值
        bClassAl.aMethodTwo();// BClass的aMethodTwo方法 没有super.aMethodOne();所以不调父类aMethodTwo
        bClassAl.getFatherVar();
    }
}

.
.
输出:

AClass static代码块
BClass static代码块
AClass 普通代码块
AClass 无参构造方法
BClass 普通代码块
BClass 无参构造方法
=========
AClass 普通代码块
AClass 无参构造方法
BClass 普通代码块
BClass 带参构造方法!
调用父类的非私有变量:10
====================
AClass 普通代码块
AClass 无参构造方法
BClass 普通代码块
BClass 带参构造方法!
调用父类的非私有变量:10
====================
AClass 普通代码块
AClass 无参构造方法
BClass 普通代码块
BClass 带参构造方法!
调用父类的非私有变量:10
aMethodOne
子类Override的aMethodOne方法 并且调用super.aMethodOne();
调用父类的非私有变量:55
====================
AClass 普通代码块
AClass 无参构造方法
BClass 普通代码块
BClass 带参构造方法!
调用父类的非私有变量:10
子类Override的aMethodTwo方法 不调用super.aMethodTwo();
调用父类的非私有变量:10

通过这个例子,我们可以清楚地看到

  • 1、静态代码块只会随着类的加载加载一次,优先于对象

  • 2、子类只可以继承父类的非private的变量方法,无法继承代码块构造方法

  • 3、当子类被实例化时,会先调用父类的无参构造方法。

  • 子类从父类继承的变量和方法是独立的,不会受到其他子类的影响。
    (bClass2改变父类的变量不会影响bClass3继承到的变量)

  • 4、子类复写父类的方法,如果不调用 super.所复写方法名称 那么对应父类方法将不会执行,也就是说,这个方法就相当一个普通的方法,没有从父类继承到什么。
    (绝大多数情况下是需要调用 super.所复写方法名称 的,但是有时候我们个别子类不想要父类方法的初始化逻辑,我们可以灵活选择是否保留 )

四、overload和override

方法重载(overload)
1.必须是同一个类
2方法名一样
3参数类型不一样或参数数量不一样

方法的重写/复写(override)

子类对父类方法的复写

两同两小一大原则:

两同:
方法名相同,参数类型相同

两小:
子类返回类型小于等于父类方法返回类型,若为基本类型或者void则必须相同
子类抛出异常小于等于父类方法抛出异常,

一大:
子类访问权限大于等于父类方法访问权限。

实例一下:

AClass

public class AClass {
    public int number = 10;
    protected void changeNumber(int i){
        setNumber(100);
        System.out.println("父类 changeNumber:  "+number);
        
    }
    
    public int setNumber(int i) {
        number = i;
        System.out.println("父类 number:  "+number);
        return number;
    }
}

.
.
BClass

public class BClass extends AClass{

    // 这个复写方法的访问权限比父类大,也就是两者访问权限不一致,但是也是对那个方法的复写
    @Override
    public void changeNumber(int i) {
        super.changeNumber(i);
        setNumber(i);
    }
}

.
.
TrtExt

public class TrtExt{
    public static void main(String[] args) {
        BClass bClass2 = new BClass(); 
        bClass2.changeNumber(70);
    }
}

输出:


父类 number:  100
父类 changeNumber:  100
父类 number:  70

我们看到,其实并不是复写的方法就需要和父类方法完全一致的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容

  • 一:java概述:1,JDK:Java Development Kit,java的开发和运行环境,java的开发工...
    ZaneInTheSun阅读 2,582评论 0 11
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,295评论 18 399
  • 、6一、基本知识 1.JDK和JRE的区别 答:JDK是java语言开发工具包,包含JRE和开发工具(javac....
    梦游的沙师弟阅读 1,141评论 0 4
  • 前言:最近感冒的不太想去面试,在家就对Java se的基础做了一些小总结 1.JDK和JRE的区别 一 基础知识 ...
    AntCode阅读 1,096评论 0 1
  • 写代码: 1,明确需求。我要做什么? 2,分析思路。我要怎么做?1,2,3。 3,确定步骤。每一个思路部分用到哪些...
    横冲直撞666阅读 333评论 0 0