世界微尘里,吾宁爱与憎
继承与多态
继承与多态

继承与多态

多态转换

子类的每个对象也是超类的对象,程序中出现超类对象的任何地方都可以使用子类对象替换,换句话说,声明为超类的变量可以引用子类的 象,声明为存储超类的数组可以存储子类的对象,但是声明为超类的,无法调用其子类的方法或者变量.

数组转换规则

在Java中,一个超类数组允许被转换成其子类的数组

Manager[] mangers=new Manager[10];
Employee[] staff=mangers;

这与多态间的转换类似,Employee数组中的存储对象无法调用Manger中的内容

子类构造器

由于父类的构造器不能访问其子类的私有字段,所以必须通过一个构造器来初始化这些私有字段,可以利用特殊的super语法调用这个构造器,其使用方法类似于在父类中使用this构造构造器

如果子类的构造器没有显式的调用父类的构造器,将自动调用超类的无参数构造器,如果父类没有无参数的构造器,并且在子类的构造器中又没有显式的调用父类的其它构造器,Java编译器就会报告一个错误

强制类型转换

Java程序设计语言为强制类型转换提供了一种特殊的表示法

double x=3.405;
int nx =(int) x;

同时,也可以对一个对象使用强制类型转换

Employee staff=new Employee[3];
Manager boss=(Manager) stafff[1];

进行该种强制类型转换的唯一原因便是,它可以将子类数组中引用成父类对象的变量复原成子类对象

综上所述,如果将一个子类引用赋给父类变量,编译器是允许的,如果将一个父类的引用赋给一个子类变量的话,这时候就需要用到强制类型转换了

抽象类

使用关键字abstract定义抽象类或抽象方法,具有一个或多个抽象方法的类必须被定义为抽象类

抽象方法充当着占位方法的角色,他们在子类中允许被实现,在子类中,如果仍有一部分抽象方法没有被定义,那么,该子类也必须被定义为抽象的

抽象类不能实例化,如果将一个类声明为abstract,就不能创建这个类的对象,而只能创建这个类子类的对象

var people =new Person[2];
people[0]=new Employee(...);
people[1]=new Student(...);
for (Person p;people)
  System.out.println(p.getname()+","+p.getDesciption);

这里,getDesciption在Person类中是一个抽象方法,虽然不能构造抽象类中的对象,但是Person类的变量可以引用其子类的对象,而其子类中定义了getDesciption方法,但是,如果省略了Person类中的抽象方法,就不能在变量p上调用getDesciption方法了

访问控制修饰符

  • private-仅对本类可见
  • public-对外部完全可见
  • projected-对本包和所有子类可见
  • 默认-对本包可见

Object类

Object类是所有类的始祖,在Java中每个类中都扩展了Object

equals()

Object类中的equals方法用于检测一个对象与另一个对象是否相等,检测原理为检测两个对象中的所有变量是否相等

在子类中定义equals方法时,首先调用父类的equals,如果检测失败,对象就不可能相等,如果超类中的字段都相同,再比较子类中的实例字段

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

具体参见文章 如何编写一个完美的equals()方法

hashcode()

返回对象的散列码,散列码可以是任意的整数,包括正数和负数,两个相等的对象要求返回相等的散列码

默认的hashcode方法是根据对象的存储地址导出的,这就意味着即使两个对象的字段都相同,但是返回的是不同的散列码

一般来说,因为两个相等的对象㤇反向两个相等我的散列码,所以需要要判断两个对象是否相等,而这个功能是由equals()函数实现的,所以如果你在子类中重新定义了equals函数,就需要在子类中重新定义hashcode方法

toString()

返回表示该对象值的字符串,要在自定义的类中覆盖这个方法,只要一个对象与一个字符串使用+号连接,编译器就会自动调用toString方法来或者这个对象的字符串描述

getClass()

返回包含对象信息的类对象

对象包装器与自动装箱

所有的基本类型都有一个对应的类,比如int类型对应Integer类,char类型对一个Character类,这些类统称为包装器

包装器是final类,无法被继承,同时也无法修改其中的值

在泛型数组列表中应用比较频繁,因为泛型数组列表只可以包含对象,所以ArrayList<int>这样是不被允许的,必须写成ArrayList<Integer>

不必担心,当你向泛型数组列表中添加元素时,可以直接添加int变量,该int变量会被自动转换成Integer对象,这种特性成为自动装箱

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

相反的,Integer也可以赋给一个int值,这种特性成为自动拆箱

对于Integer n=3,编译器将先进行自动拆箱,然后进行自增运算,最后再将结果装箱

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注