Java日常学习总结之继承篇

Java日常学习总结之继承篇

想要了解更多欢迎大家访问我的个人博客:AllenMistake的小窝

让我们一起进步啊

目录

类,超类,子类

super

  1. super与this
    有些人认为super 与this 引用是类似的概念, 实际上, 这样比较并不太恰当。这是因为super 不是一个对象的引用, 不能将super 赋给另一个对象变量, 它只是一个指示编译器调用超类方法的特殊关键字。

  2. super与构造
    当子类构造的时候,由于不能对其超类的私有成员进行访问,只能调用超类的构造器。如果子类的构造器没有显式地调用超类的构造器, 则将自动地调用超类默认(没有参数)的构造器。
    C++ 注释: 在C++ 的构造函数中, 使用初始化列表语法调用超类的构造函数, 而不调用super。在C++ 中,Manager 的构造函数如下所示:

    Manager::Manager(Stri ng name, double salary, int year, int month, int day) // C++
    : Employee(name, salary, year , month , day)
    {
        bonus = 0;
    }
    

超类与子类引用关系

超类可以引用子类,但是,不能将一个超类的引用赋给子类变量。在下面的例子中,超类虽然引用了子类,变量staff[0]与boss引用同一个对象。但编译器将staff[0]看成Employee对象。

Manager boss = new Manager(. . .);
Employee[] staff = new Employee[3];
staff[0] = boss;//Correct Employee超类可以引用其子类Manger
boss = staff[0];//Error
staff[0].setBonus(5000);//Error

在Java 中,子类数组的引用可以转换成超类数组的引用, 而不需要采用强制类型转换。例如,下面是一个经理数组

Manager[] managers = new Manager[10];

将它转换成Employee[]数组完全是合法的:

Employee[] staff = managers; // OK

这样做肯定不会有问题,请思考一下其中的缘由。毕竟,如果manager[i] 是一个Manager, 也一定是一个Employee。然而, 实际上,将会发生一些令人惊讶的事情。要切记managers和staff引用的是同一个数组。现在看一下这条语句:

staff[0] = new Employee("Harry Hacker", . . .) ;

编译器竟然接纳了这个赋值操作。但在这里, staff[0]与manager[0]引用的是同一个对象,似乎我们把一个普通雇员擅自归入经理行列中了。这是一种很忌伟发生的情形,当调用managers[0].setBonus(1000) 的时候,将会导致调用一个不存在的实例域, 进而搅乱相邻存储空间的内容。
为了确保不发生这类错误, 所有数组都要牢记创建它们的元素类型,并负责监督仅将类型兼容的引用存储到数组中。例如,使用new managers[10]创建的数组是一个经理数组。如果试图存储一个Employee 类型的引用就会引发ArrayStoreException异常

类型转换

  • 只能在继承层次内进行类型转换。
  • 在将超类转换成子类之前,应该使用instanceof 进行检查。

在一般情况下,应该尽量少用类型转换和instanceof 运算符。

抽象类abstract

提示:许多程序员认为,在抽象类中不能包含具体方法。建议尽量将通用的域和方法(不管是否是抽象的)放在超类(不管是否是抽象类)中。

继承抽象类可以有两种选择。
一种是在抽象类中定义部分抽象类方法或不定义抽象类方法,这样就必须将子类也标记为抽
象类;另一种是定义全部的抽象方法,这样一来,子类就不是抽象的了。
抽象类不能被实例化。可以定义一个抽象类的对象变量,但是它只能引用非抽象子类的对象,这个时候,利用这个对象变量调用抽象类的抽象方法,会自动向下寻找,也就是实际调用的是其子类的方法。

Object所有类的超类

equals

在Object 类中,这个方法将判断两个对象是否具有相同的引用。

泛型数组列表

ArrayList

  1. 构造形式

    ArrayList<Employee> staff = new ArrayList<Employee>();
    

    Java SE 7 中, 可以省去右边的类型参数:

    ArrayList<Employee> staff = new ArrayList<>()
  2. 添加元素
    add方法
    如果调用add且内部数组已经满了, 数组列表就将自动地创建一个更大的数组,并将所有的对象从较小的数组中拷贝到较大的数组中。
    警告:分配数组列表, 如下所示:

    new ArrayList<>(lOO) // capacity is 100
    

    它与为新数组分配空间有所不同:

    new Employee[100] // size is 100
    

    数组列表的容量与数组的大小有一个非常重要的区别。如果为数组分配100 个元素的存储空间,数组就有100 个空位置可以使用。而容量为100 个元素的数组列表只是拥有保存100 个元素的潜力( 实际上,重新分配空间的话,将会超过100), 但是在最初,甚至完成初始化构造之后,数组列表根本就不含有任何元素。

    C++ 注释: ArrayList类似于C++ 的vector 模板。ArrayList 与vector 都是泛型类型。但是C++ 的vector 模板为了便于访问元素重栽了[ ] 运算符。由于Java 没有运算符重栽,所以必须调用显式的方法。此外,C++ 向量是值拷贝。如果a 和b 是两个向量,赋值操作a = b 将会构造一个与b 长度相同的新向量a,并将所有的元素由b 拷贝到a, 而在Java 中,这条赋值语句的操作结果是让a和b引用同一个数组列表。

  3. 总结

    • 不必指出数组的大小。
    • 使用add 将任意多的元素添加到数组中。
    • 使用size() 替代length 计算元素的数目。
    • 使用a.get(i) 替代a[i] 访问元素。

这就是Java 中不尽如人意的参数化类型的限制所带来的结果。鉴于兼容性的考虑, 编译
器在对类型转换进行检査之后, 如果没有发现违反规则的现象, 就将所有的类型化数组列表
转换成原始ArrayList 对象。在程序运行时, 所有的数组列表都是一样的, 即没有虚拟机中
的类型参数。因此,类型转换ArrayListArrayList<Employee> 将执行相同的运行时检查。

对象包装器与自动装箱

  1. 对象包装器
    有时, 需要将int这样的基本类型转换为对象。所有的基本类型都冇一个与之对应的类。通常,这些类称为包装器(wrapper) 。
    这些对象包装器类拥有很明显的名字:Integer、Long、Float、Double、Short、Byte、Character 、Void 和Boolean
    下面是声明一个ArrayList里面存放int型

    ArrayList<Integer> list = new ArrayList<>()

    这种方式适用于小型集合,因为其效率比整型数组int[]要低得多,但是添加成员的方便程度要比整型数组要高。

  2. 自动装箱
    幸运的是, 有一个很有用的特性, 从而更加便于添加int 类型的元素到ArrayList<lnteger>中。下面这个调用

    list.add(3);
    

    将自动地变换成

    list.add(Integer.value0f(3)) ;
    

    这种变换被称为自动装箱(autoboxing)。

枚举类

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值