本文总结《核心技术》5.1和5.2
主要包括以下内容
1、超类与子类 2、多态 3、动态与静态绑定 4、final
5、抽象类 6、protected 7、Object中的方法(equal/hashCode/toString)
5.1 超类与子类
超类即父类、基类;子类即派生类。子类继承父类,判断继承关系的一个依据:(is-a)关系。
5.1.1 几点规则子类不能访问父类的私有域(如super.name错误);需要调用时要用super.getName(),注意在写子类的getName()时,不能直接使用getName(),会陷入无限循环。
super不是一个引用,只是一个指示编译器调用超类方法的关键字。
只能在子类中增加域、方法;而不能删除。
super(参数)可以调用父类相应的构造器,但它必须位于子类构造器的第一行;假如编写子类时未定义构造器,编译器将自动调用父类无参构造器;
倘若上述情况,父类已经定义了一个有参构造器,那么将报错
可以看出this/super的两个作用引用隐式参数/超类
构造器
5.1.2 多态
多态就是父类变量可以引用一个子类对象。如Employee父类和Manager子类
Employee[] a = new Employee[3];
Manager boss = new Manager("D", 110,1,1,1);
a[0] = boss; //OKa[0].setBonus()//NO,setBonus()是Manager子类独有的方法,a中无对应方法//e是一个Employee实例对象boss = e;//NO,不能将父类对象赋值给子类引用;因为不是所有的雇员都是老板!
5.1.3 动态绑定
对于类中的一个方法有一个方法签名:(名字、参数类型)构成了他的id;而返回类型并不在其中,因此:子类重写父类的方法时,必须保证方法的返回类型一致。
动态绑定:调用的方法依赖于隐式参数的实际类型,在运行时完成绑定;
静态绑定:private/static/final修饰的方法
方法表:定义 方法签名+实际调用方法,如:
在子类覆盖父类方法时,子类方法的可见性>=父类方法;如父类方法public,子类也必须是。
5.1.4 final:阻止继承
final类:不能扩展,其中的所有方法均final
final方法:不能继承、覆盖
final域:不能改变
内联-代码的优化?没看懂
5.1.5 强制类型转换
//staff是一个Employee对象数组,但staff[1]引用了一个Manager对象
//这里通过强制类型转换,将staff[1]转换为原有类型,以便使用扩展方法如getBonus()
if (staff[1] instanceof Manager)//当staff[1]
{
Manager boss=(Manager)staff[1]
}
5.1.6 抽象类
abstract关键字
抽象类中可以有不抽象的方法,但抽象方法必在抽象类中
抽象类不能实例化,必须子类实现方法后实例,但允许作为实例对象的引用,如
Person A = new Student(...);//Person抽象,Student非抽象
5.1.7 protected
目的:使得子类可以访问父类的域
总结一下四种可见性修饰符
(1)private 仅本类可见
(2)public 所有类可见
(3)protected 本类可见,包括子类
(4)默认 本包内可见
5.2 Object — 所有类的超类
由于超类可以作为所有子类的引用,因此Object可以引用任何类型的对象;在java中,除了基本类型(数值、字符、布尔)外,连数组都是对象,如Object obj = new int[10];下面介绍Object中的几个方法:
5.2.1 equals()
用来对两个对象是否相等进行判断
class A
{
public boolean equal(Object obj)
{
if(!obj instance A) //当当前类非要比较的类时,直接返回错误 return false;
A now = (A) obj;//将传入类强制转换为A return obj.value==this.value;//比较的值 }
}
5.2.3 hashCode()
一种将对象、数值等映射为整数(可负)的方法;
String类:其中自定义的hashCode方法是将字符串值映射为值,因此hashCode的返回值一样意味着内容一样
对象:返回存储地址,可以自定义覆盖hashCode
一个更安全的方法是Objects.hashCode(A),当A为空时返回0;Objects.hash(多个参数)
5.2.4 toString()
一个转换为字符串的方法;对于基本类型(不在Object范围中),可以用 ""+X的方式来实现。
数组中有Arrays.toString(数组名)或Arrays.toString(高维数组名)
可以对自定义的类都重写一下toString()用来输出需要的信息。
//一个对象的toString()返回的值:类名@(对象地址的hashCode)//例如以下代码Employee a = new Employee("sss", 11, 1, 1, 1);
System.out.println(a.toString());
System.out.println(Integer.toHexString(a.hashCode()));
//返回结果Employee@3d4eac69
3d4eac69
还有getClass()方法
Class c = a.getClass();//这里定义一个类文件对象c,存储a的类
System.out.println(c.getMethods());//反编译
System.out.println(c.getName());//获得类名
//结果
[Ljava.lang.reflect.Method;@75b84c92
Employee