Inheritance - Core Java一些问题

来源:互联网 发布:mac解压rar文件的软件 编辑:程序博客网 时间:2024/05/23 13:11
  1. HashCode

new Double(double d)

Double 类用来生成一个包含double数值的对象,可以进行许多操作,例如生成哈希码:

new Double(12,7).hashCode

注意:如果重定义equals(),则需要冲定义hashCode()

生成哈希码可以用x.hashCode(),不过更建议使用Object.hashCode(x)。其中x为要生成哈希码的对象。

Object.hashCode(x) : null安全的哈希码。如果对象是null,返回0,如果不是null,则调用hashCode

Object.hash(par 1, par 2, …)还可以组合多个哈希值,例如:

Object.hash(name, salary, hireDay)

equals与hashCode的定义必须一致,如果x.equals(y)返回true,则x.hashCode()与y.hashCode()的值必须一样。例如,如果定义Employee.equals比较雇员ID,则hashCode方法需要求ID的哈希码,而不是姓名,薪水的哈希码。

2.对于一个reference variable,Java编译器按照它声明的Type工作。如果a是SuperClass类型变量,b是subClass变量,将b赋值给a,则通过a不能调用b的方法。需要将b进行类型转换才可以。

3.类型转换
下转换,需要通过(Type)运算符,例如:

SubClass b = new SubClass();SuperClass a = b;SubClass c = (SubClass) a; //下转换

对于上转型,不需要强制类型转换符,因为子类对象肯定可以看做父类对象:

SubClass b =new SubClass();SuperClass a = b;//上转换

4.多态:一个reference variable可以指示多种实际类型的现象。在运行时虚拟机能自动的选择调用哪个方法的现象称为动态绑定。
动态绑定: 实例方法(instance method)与引用变量(Reference variable)实际引用的对象的方法绑定,这种绑定是在运行时有Java虚拟机动态决定的。虚拟机一定调用reference variable所引用对象实际类型最合适的那个类的方法。例如:

public class A {    void method () {System.out.pritnln("Base");}    void test() {method();}}public class B extends A {    void method() {System.out.println("Sub");}    public static void main(String[] args) {    new A().test();//调用A的method方法    new B().test();//调用B的method方法    }}

运行结果为:

BaseSub

通过上例,可以体会到,在runtime时,当通过B类的instance去调用一系列instance method(包括一个方法调用另一个方法),将优先和B类本身包含的instance method动态绑定,如果B类没用定义这个instance method,才会与从父类A中继承来的实例方法动态绑定。

5.静态绑定:指在编译阶段就已经绑定。
(1) 静态方法与Reference variable所声明的类型的方法绑定,这种绑定属于静态绑定。
(2)成员变量(静态和实例变量)与引用变零所声明的类型的成员变量绑定。

6.子类中定义的方法不能访问父类的private域,可以通过继承父类中的方法来访问,例如:

class Employee {    private name;    public String getName() {    return name    }} class Manager {    System.out.println (name) //不可以直接访问name,因为name是Employee class的private field    System.out.println (getName());//通过调用继承的方法访问name,getName又称为接口}

7.super和this
如果子类需要调用超类的方法,可以用super实现,super只是一个指示编译器调用超类方法的关键字。例如:

class Employee {    private double salary;    public double getSalary() {    return salary    }}class Manager extends Employee {    private double bonus;    public double getSalary() {    double baseSalary = super.getSalary();//调用Employee类的方法,获得salary的值    return baseSalary + bonus;    }   

由于Manager类的构造器不能访问Employe类的私有域,所以必须利用Employee的构造器对私有域初始化,子类构造器第一行为:super()调用超类的构造器。
this是当前对象的引用,例如:

class Employee {    private double salary;public void setSalary(double salary) {    this.salary = salary;//this.salary表示 class field, 等号右边的salary为method的参数    }

8.置换法则:程序中出现超类对象的任何地方都可以用子类对象替换,例如:

Employee e = new Employee();e = new Manager();

9.equals方法:
(1) 为了防备比较对象可能为null的情况,需要使用Objects.equals方法,如果两个参数都为null,则Objects.equals(a, b)返回true,如果其中一个为null,则返回false; 如果两个参数都不为null,则调用a.equals(b)。程序示例:

return Object.equals(name, other.name)         && salary == other.salary        && Objects.equals(hireDay, other.hireDay);

在子类中定义equals方法,首先需要调用超类的equals,如果检测失败,对象肯定不相等,如果超类中的域都相等,就需要比较子类中的实例域。例如:

class Manager extends Employee {    public boolean equals (Object oherObject) {        if (!super.equals(otherObject) return false;        Manager other = (Manager) otherObject;        return bonus == other.bonus;        }    }

(2) 通过getClass()来获得对象所属的类。通过instanceof来判断对象是否类的实例,子类对象是超类的实例。

if ((new Manager()) instanceof Employee) //true,Manager是Employee的子类if ((new Employee() instanceof Manager) //false, Employee是Manager的超类,不是Manager的实例

(3) 如果子类定义自己的equals方法,则通过getClass()方法判断是否属于同一类。如果equals方法由超类定义,则通过instanceof,判断子类是否继承于超类,然后调用equals方法。

(4)@Override判断是否进行覆盖,例如:

@Override public boolean equals (Object other)

如果没有覆盖超类方法,编译器会提示错误。

10.Override超类方法时,子类中方法的名称和参数必须和被覆盖方法相同,但是返回值可以不同。例如:

class Employee {    ...    public Employee creatStaff () { //该方法返回一个Employee对象    }class Manager {    ...    public Manager creatStaff () { //覆盖Employee中的creatStaff方法,但是返回Manager对象    }

10.toString方法:将对象以字符串表示。
每个class都应该定义自己的toString方法,只要对象与一个字符串通过操作符 “+” 连接起来,Java编译器就会自动的调用toString方法,以便获得对象的字符串描述。toString方法例子如下:

class Employee {    ...    @Override public String toString() {        return "Employee[name="                 + getName()                 + ",Salary="                 + getSalary()                 + ",hireDay="                 + getHireDay()                + "]";    }

子类可以继承超类的toString,这样就不需要重复编写代码,例如:

class Manager extends Employee {    ...    @Override public String() {    return super.toString() + "[bonus =" + getBonus() + "]";    }}

Object类定义了toString方法,用来打印输出对象所属的类名和散列码。
数组的输出:数组继承了Object类的toString方法,如果直接打印数组,会输出数组的类名和散列码。例如:

int[] num = {1,2,3};System.out.println ("" + num);输出:[I@1a46e30

想要输出数组元素,需要调用Array类中的toSting方法,例如:

System.out.println(Arrays.toString(num));输出:[1,2,3]

11.ArrayList类
初始化:ArrayList var = new Array<>();
例如:ArrayList staff = new Array<>();
可以指定初始内部数组的大小,例如:
ArrayList staff = new Array<>(100); //初始内部数组有容纳100个元素的潜力,但是如果没有元素加入,它是空的。

ArrayList的机制:ArrayList维护了一个内部数组,通过add方法往里面增加元素,如果内部数组满了,就会自动开辟一个更大的数组,将原内部数组的元素复制过去。如果知道元素的数量,事先指定内部数组的大小,以容纳全部元素,则可以省去新建数组和复制的操作。

0 0
原创粉丝点击