【java学习笔记】第六章 继承与多态

继承是为了避免重复的行为定义,但并不是所有出现重复行为的情境下都要使用继承来解决。如何正确判断使用继承的实际,及继承后如何活用多态,才是学习继承时的重点,也是我们看到优秀项目时需要思考的重点。

继承

1、private成员也可继承,但只可通过父类方法进行操作。

2、多态与is-a。多态就是,通过单一接口操作多种类型的对象。如下展示三两个代码:第一个编译不通过,第二个编译通过但执行报错。(Student、Teacher继承people)

People p1 = new Student();
Student s1 = p1;
Peopel p = new Teacher();
Student s = (Student)p;

3、abstract:这个解释蛮好记的,表示这个类有缺失,不可以直接被实例化。如果被继承,子类必须abstract或者实现父类的抽象方法。令注权限关键字与范围如下表,鉴于所有都可以在类内部获得,这里就不单独列出来了。(为了完美的三角形阵型)

关键字相同包不同包子类不同包非子类
publicYYY
protectedYYN
无修饰YNN
privateNNN

如果继承,子类的修饰符的范围不可小于父类(粑粑同意做的事情儿子不同意,多没面子)。jdk5之前,如果子类继承方法返回类型是父类方法返回类型的子类,则报错,就是…嗯下面代码5之前会报错,5后就不会了。

public class Bird{
    public Bird copy(){
        return new Bird();
    }
}

public class Chick extends Bird{
    public Chick copy(){
        return new Chick();
    }
}

子类构造函数默认调用父类构造函数。之前说过,如果自定义带参构造函数,则系统不会自动为类构造无参函数。

4、子类如果想要调用父类的构造函数可以使用super,但this和super只能选择一个使用,且必须放在构造函数的第一行。

继承语法细节

1、所有类都是object的子类,子子类…。(默认继承)

2、继承中的final:如果修饰类,表示不可再被继承(String就是一个典型的final类,不可被继承);如果修饰方法,不可再被子类重新定义;如果修饰属性,则该属性需在定义时明确赋值或在其构造函数中明确赋值,且赋值后不会再改变

3、垃圾回收(GC):JVM自动识别无法通过变量参考的对象并回收,包括形成孤岛的对象们(互相调用,但未产生实际使用)。GC回收对象前调用对象的finalize()方法,但尽量避免使用,垃圾回收是java面试中常问到的一点,也内容也比较深,后面需要重点学习。

4、再看抽象类:抽象方法只能出现在抽象类中,书里用 模板方法模式(Template Method) 来展示抽象类的使用。如下例,当我们不确定使用什么方式获取猜测的数字,但是已经确定猜数的整个流程,就可以使用这种模式:

//抽象父类
public abstract class GuessGame {
    //执行猜数过程
    public void go(){
        int secretNum = (int)(Math.random()*10);
        int guess = 0;
        do{
            printPrompt();
            guess = getGuessNum();
        } while (guess != secretNum);
        printSucessMessage(secretNum);
    }

    //通过不同的方式,获取输入猜测的数字
    public abstract int getGuessNum();

    //输出提示
    public abstract void printPrompt();

    //输出成功的提示消息
    public abstract void printSucessMessage(int secretNum);
}

子类在继承父类的时候,必须实现抽象方法,在子类中确定通过什么方式获取猜测的数字。

public class ConsoleGame extends GuessGame{
    private Scanner scanner = new Scanner(System.in);
    @Override
    public int getGuessNum() {
        return scanner.nextInt();
    }

    @Override
    public void printPrompt() {
        System.out.println("请输入猜测的数字(1~10):");
    }

    @Override
    public void printSucessMessage(int secretNum) {
        System.out.println("猜对了,结果为:"+secretNum);
    }
}

调用方式如下:

        ConsoleGame consoleGame = new ConsoleGame();
        consoleGame.go();

部分课后题:

解析:因为hashCode是Object的一个public方法,因为所有的类追究到其顶部,都是Object的子类,且子类继承父类的方法时权限关键字不得小于父类,所以这里会显示编译失败。

解析:若子类的构造函数不调用父类构造函数,默认调用父类的无参构造函数。而如果一个类已经有带参的构造函数,jvm不会再自动构建一个无参构造函数,需要编程人员指定无参构造函数。这种情况可以有两种解决办法:在Some中构造一个无参的构造函数;或者在Other构造函数的第一行通过“super(x)”来调用父类带参构造函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值