12 继承 super

1 继承
1.1概念
继承是面向对象最显著的一个特征
继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并扩展新的能力.
Java继承是会用已存在的类的定义作为基础建立新类的技术
新类的定义可以增加新的数据或者新的功能,也可以使用父类的功能,但不能选择性的继承父类(超类/基类)
这种继承使得复用以前的代码非常容易,能够大大的缩短开发的周期,降低开发费用.

1.2 特点
使用extends关键字来表示继承关系
相当于子类把父类的功能复制了一份
Java只支持单继承
继承可以传递(爷爷/儿子/孙子这样的关系)
不能继承父类的私有成员
继承多用于功能的修改,子类可以在拥有父类功能的同时,进行功能拓展
像是is a的关系
1.3 练习:继承入门案例
创建包: cn.tedu.oopextends
创建类: TestExtendsDemo.java

package cn.tedu.oopextends;
/*本类用于继承的入门案例*/
public class TestExtendsDemo {
    public static void main(String[] args) {
        //5.创建Animal类/Catlei/MiaoMiao类的对象
        Animal a = new Animal();
        Cat c = new Cat();
        MiaoMiao m = new MiaoMiao();
        //6.利用创建好的3个对象来调用Animal类中定义的eat()
        a.eat();
        c.eat();
        m.eat();
        /*3.继承具有传递性,爷爷的功能会传给爸爸,爸爸的功能会传给孙子*/
    }

}
//1.创建爷爷类Animal
class Animal{
    //4.定义爷爷类的普通方法
    public void eat(){
        System.out.println("小动物吃啥都行~");
    }
}
//2.创建爸爸类Cat,并与Aniaml类建立继承关系
/*1.我们通过extends关键字建立子类与父类的继承关系,子类 extends 父类*/
/*2.java只支持单继承:一个子类只能有一个父类,但一个父类可以有多个子类*/
/*7.继承是一种is a 的关系,比如小猫是小动物,DingDang是猫
* 要求子类必须是父类的一种继承结构,依赖性非常强,强耦合*/
class Cat extends Animal{
    //7.定义属性--成员变量
    int a = 10;
    private int b = 100;
}
//3.1创建孙子类DingDang,并与Cat类建立继承关系
class DingDang extends Cat{
    /*4.子类可以拥有自己独有的方法,实现功能的拓展,青出于蓝而胜于蓝*/
    //8.定义孙子类自己特有的方法
    public void studyJava(){
        /*5.子类在继承父类以后,相当于把父类的功能进行了复制*/
        System.out.println(a);//子类可以使用父类的属性a
        /*6.父类的私有资源子类不可以使用,原因是私有资源不可见*/
        //System.out.println(b);//子类不可以使用父类的私有资源,这么写会报错
    }
}
//3.2创建孙子类MiaoMiao,并与Cat建立继承关系
class MiaoMiao extends Cat{

}

2 super
可以通过这个关键字使用父类的内容,Super代表的是父类的一个引用对象
注意:在构造方法里,出现的调用位置必须是第一行

3 方法重写Override
继承以后,子类就拥有了父类的功能
在子类中,可以添加子类特有的功能,也可以修改父类的原有功能
子类中方法的签名与父类完全一样时,会发生覆盖/复写的现象
注意: 父类的私有方法不能被重写
重写的要求:两同两小一大
两同:方法名 参数列表 要完全一致
两小:
子类返回值类型小于等于父类的返回值类型(注意此处说的是继承关系,不是值大小)
子类抛出异常小于等于父类方法抛出异常
一大:子类方法的修饰符权限要大于等于父类被重写方法的修饰符权限
4 继承的用法
4.1 练习:成员变量的使用
创建包: cn.tedu.oopextends
创建类: TestExtends1.java

package cn.tedu.oopextends;
/**本类用于测试继承中成员变量的使用*/
public class TestExtends1 {
    //5.创建程序的入口函数main
    public static void main(String[] args) {
        //6.创建对象进行测试
        Son s = new Son();
        s.eat();
    }
}
//1.创建父类
class Father{ 
    //7.在父类中定义属性
    int sum = 1000;
    int count = 888;
}
//2.创建子类Son
class Son extends Father{
    //4.2定义成员变量
    int sum = 100;
    //3.定义子类的普通方法
    public void eat() {
        //4.1在普通方法中定义子类的局部变量
        int sum = 10;
        System.out.println(sum);//10,变量的就近原则,打印的是局部变量
        System.out.println(this.sum);//100,使用的是this指定的成员变量sum
        
        /**在子类中使用父类的sum资源,需要使用super.进行指定
         * super是表示父类的一个对象引用
         * 可以理解成Father super = new Father();
         * */
        System.out.println(count);//使用的是父类的资源
        System.out.println(super.sum);
        //1000,使用的是super指定的父类的成员变量sum
    }
}

4.2 练习:成员方法的使用
创建包: cn.tedu.oopextends
创建类: TestExtends2.java

package cn.tedu.oopextends;
/*本类用于测试继承中成员方法的使用*/
//重写:继承后,子类对父类功能不满意,就可以重写
//重写的规则:两同 两小 一大
//方法名相同,参数列表相同
//子类方法的返回值类型 <=父类方法的返回值类型
//子类方法抛出的异常类型 <= 父类方法抛出的异常类型【还没学到,现在不用看】
//子类方法的修饰符 >= 父类方法的修饰符
//TIPS:子类无权修改父类的私有方法
public class TestExtends2 {
    public static void main(String[] args) {
        //4.创建父类与子类对象进行测试
        Father2 f = new Father2();
        Son2 s = new Son2();
        f.eat();
        /**1.继承后,子类可以使用父类的所有非私有功能*/
        s.eat();
        s.study();
    }
}
//1.创建父类
class Father2{
    //3.创建父类中的方法
    public void eat() {
        System.out.println("爸爸爱吃肉~");
    }
    public void play() {
        System.out.println("喜欢放风筝~");
    }
}
//2.创建子类,并与父类建立继承关系
class Son2 extends Father2{
    //5.创建子类特有的功能
    public void study() {
        System.out.println("快到端午了,学学包粽子吧~");
    }
    
    /**OCP原则:面向修改关闭,面向拓展开放
     *   只允许功能拓展,不允许修改原来的代码*/
    //6.修改父类原有的功能--不允许修改父类中的原代码
    //功能修改--方法的重写
    /**重写的规则:
     * 和父类的方法签名保持一致【方法名&参数列表】 
     * 子类方法的修饰符 >= 父类方法的修饰符
     * 子类返回值类型 <= 父类的返回值类型
     * 然后去修改子类中本方法的实现,父类的功能并没有被改变
     * 重写时,子类必须拥有可以重写的权限,子类无权修改父类的私有方法*/
    @Override 
    /**这是一个注解,可以理解成一个标签,用来标记此方法是不是一个重写的方法*/
    public void eat() {
        System.out.println("儿子爱吃蔬菜~");
    }
    public void play() {
        System.out.println("我爱玩电子游戏");
    }
}

4.3 练习:构造方法的使用
创建包: cn.tedu.oopextends
创建类: TestExtends3.java

package cn.tedu.oopextends;
/**本类用于测试继承中构造方法的使用*/
//总结:
//1.子类创建对象时,默认会访问父类的无参构造
//2.在子类构造方法中的第一行都有一条默认语句super()--调用父类的无参构造
//3.当父类没有无参构造时,可以通过super调用父类的其它构造方法
//4.构造方法不可以被继承!
public class TestExtends3 {
    //3.创建程序的入口函数main
    public static void main(String[] args) {
        //4.创建父类对象
        //Father2 f = new Father2("红烧肉");
        //6.创建子类对象
        Son2 s = new Son2();
    }
}

//1.创建父类
class Father2{
    /**0.构造方法可以被继承吗?--不可以!!!
     * 语法结构的要求:构造方法的方法名需要与本类类名一致,天然就不符合要求
     * */
    //5.手动添加父类的无参构造
//    public Father2() {
//        System.out.println("我是Father2的无参构造");
//    }
    //8.创建父类的含参构造
    public Father2(String s) {
        System.out.println("我是Father2的含参构造"+s);
    }
}
//2.创建子类
class Son2 extends Father2{
    //7.创建子类的构造方法
    public Son2() {
        /**1.子类的构造方法中,默认存在super(),所以创建子类对象时,默认会调用父类的无参构造*/
        /**2.在子类创建对象时,会自动调用子类的无参构造
         * 但是继承后,会先去调用父类的无参构造,再执行自己构造方法中的功能
         * */
        /**3.当父类中没有无参构造时,调用的是父类的含参构造
         * 必须要调用一个父类的构造函数*/
        super("红烧肉");
        System.out.println("我是Son2的无参构造");
    }
}

5. 拓展
5.1 this与super的区别
This代表本类对象的引用
class Cat{ this.XXX } 可以理解成: Cat this = new Cat();
super代表父类对象的引用
class Father{ }
class Son extends Father{ super.XXX }
可以理解成: Father super = new Father();
this可以在两个变量名相同时,用于区分成员变量和局部变量
this 可以在本类的构造方法之间调用,位置必须是第一条语句,注意,不能相互调用,会死循环
super是发生了继承关系以后,子类如果想用父类的功能,可以通过super调用
如果发生了重写,还想用父类的功能,需要使用super来调用
Super在调用父类构造方法时,必须出现在子类构造方法的第一条语句,而且如果父类中没有提供无参构造,子类可以通过super来调用父类其他的含参构造
5.2 重载Overload 与重写Override的区别
重载: 是指在一个类中的现象,是指一个类中有很多同名的方法,但是方法的参数列表不同
重写: 是指发生了继承关系以后(两个类),子类去修改父类原有的功能
语法规则:子类的方法签名(返回值类型 方法名(参数列表) )与父类一致
重写方法的修饰符: 子类权限 >= 父类的权限
重载的意义: 是为了方便外界对方法进行调用,什么样的参数程序都可以找到对应的方法来执行,体现的是程序的灵活性
重写的意义:是在不修改源码的前提下,进行功能的修改和拓展
(OCP原则:面向修改关闭,面向拓展开放)
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值