类的继承,枚举,反射和一些常用的方法

本文介绍了Java中的继承机制,包括子类、超类的概念,以及如何使用`extends`关键字。反射允许程序在运行时检查类的属性,动态绑定和类型转换是多态的核心。同时,文章强调了覆盖方法的原则和`final`关键字的作用。此外,还讨论了抽象方法、类型转换、`Object`类、`equals`和`hashCode`方法的重要性,以及枚举类和反射库的应用。
摘要由CSDN通过智能技术生成

继承(inheritance),利用继承,人们可以基于已存在的类构造一个新类。继承已存在的类就 是复用(继承)这些类的方法和域。

反射( reflection),反射是指在程序运行期间发现更多的类 及其属性的能力。

类 子类 超类

关键字 extends 表明正在构造的新类派生于一个已存在的类。 已存在的类称为超类 ( superclass)、 基类( base class) 或父类(parent class); 新类称为子类(subclass、) 派生类 ( derived class) 或孩子类(child class)。

在 Java 中, 所有的继承都是公有继承。

覆盖方法

然而, 超类中的有些方法对子类并不一定适用。为此,需要提供一个新的方法来覆盖(override) 超类中的这个方法。

关键字 this 有两个用途: 一是引用隐式参数,二是调用该类其他的构造器 , 同样,super 关键字也有两个用途:一是调用超类的方法,二是调用超类的构造器。

多态

一个对象变量(例如, 变量 e ) 可以指示多种实际类型的现象被称为多态( polymorphism)。

在运行时能够自动地选择调用哪个方法的现象称为动态绑定( dynamic binding)。

在 Java 中,子类数组的引用可以转换成超类数组的引用, 而不需要采用强制类型 转换。

继承层次

由一个公共超类派生出来的所有类的集合被称为继承层次( inheritance hierarchy )。

在继承 层次中, 从某个特定的类到其祖先的路径被称为该类的继承链 ( inheritance chain)

理解方法调用

阻止继承:final 类和方法

有时候,可能希望阻止人们利用某个类定义子类。不允许扩展的类被称为 final 类。如果 在定义类的时候使用了 final 修饰符就表明这个类是 final 类。

类中的特定方法也可以被声明为 final。如果这样做,子类就不能覆盖这个方法( final 类中的所有方法自动地成为 final 方法 。

类型转换

将一个值存人变量时, 编译器将检查是否允许该操作。将一个了-类的引用赋给一个超类 变量, 编译器是允许的。但将一个超类的引用赋给一个子类变量, 必须进行类型转换, 这样 才能够通过运行时的检査。

应该养成这样一个良好的程序 设计习惯:在进行类型转换之前,先查看一下是否能够成功地转换。这个过程简单地使用 instanceof 操作符就可以实现。

抽象方法

抽象方法充当着占位的角色, 它们的具体实现在子类中。扩展抽象类可以有两种选择。 一种是在抽象类中定义部分抽象类方法或不定义抽象类方法,这样就必须将子类也标记为抽 象类;另一种是定义全部的抽象方法,这样一来,子类就不是抽象的了

修饰符

1 ) 仅对本类可见 private

2 ) 对所有类可见 public:

3 ) 对本包和所有子类可见 protected。

4 ) 对本包可见—默认(很遗憾,) 不需要修饰符。

Object

Object 类是 Java 中所有类的始祖, 在 Java 中每个类都是由它扩展而来的。

如果没有明确地指出超类,Object 就被认为是这个类的超类。

可以使用 Object 类型的变量引用任何类型的对象。

equals方法

Object 类中的 equals 方法用于检测一个对象是否等于另外一个对象。在 Object 类中,这 个方法将判断两个对象是否具有相同的引用。如果两个对象具有相同的引用, 它们一定是相 等的。

equals方法的规范

1 ) 自反性:对于任何非空引用 x, x.equals(x) 应该返回 true

2 ) 对称性: 对于任何引用 x 和 y, 当且仅当 y.equals(x) 返回 true , x.equals(y) 也应该返 回 true。

3 ) 传递性: 对于任何引用 x、 y 和 z, 如果 x.equals(y) 返 N true, y.equals(z) 返回 true, x.equals(z) 也应该返回 true。

4 ) 一致性: 如果 x 和 y 引用的对象没有发生变化,反复调用 x.eqimIS(y) 应该返回同样 的结果。

5 ) 对于任意非空引用 x, x.equals(null) 应该返回 false,

完整的equals方法建议

1 ) 显式参数命名为 otherObject, 稍后需要将它转换成另一个叫做 other 的变量。

2 ) 检测 this 与 otherObject 是否引用同一个对象: if (this = otherObject) return true; 这条语句只是一个优化。实际上,这是一种经常采用的形式。因为计算这个等式要比一 个一个地比较类中的域所付出的代价小得多。

3 ) 检测 otherObject 是否为 null, 如 果 为 null, 返 回 false。这项检测是很必要的。 if (otherObject = null) return false;

4 ) 比较 this 与 otherObject 是否属于同一个类。如果 equals 的语义在每个子类中有所改 变,就使用 getClass 检测: if (getClass() != otherObject.getCIassO) return false; 如果所有的子类都拥有统一的语义,就使用 instanceof 检测: if (!(otherObject instanceof ClassName)) return false;

5 ) 将 otherObject 转换为相应的类类型变量: ClassName other = (ClassName) otherObject 6 ) 现在开始对所有需要比较的域进行比较了。使用 =比较基本类型域,使用 equals 比 较对象域。如果所有的域都匹配, 就返回 true; 否 则 返 回 false。

hasCode()方法

散列码( hash code ) 是由对象导出的一个整型值。散列码是没有规律的。如果 x 和 y 是 两个不同的对象, x.hashCode( ) 与 y.hashCode( ) 基本上不会相同。

Equals 与 hashCode 的定义必须一致:如果 x.equals(y) 返回 true, 那么 x.hashCode( ) 就必 须与 y.hashCode( ) 具有相同的值。

toString方法

在 Object 中还有一个重要的方法, 就是 toString方法, 它用于返回表示对象值的字符 串。

绝大多数(但不是全部)的 toString方法都遵循这样的格式:类的名字,随后是一对方括号括起来的域值。

随处可见 toString方法的主要原因是:只要对象与一个字符串通过操作符“+“连接起 来,Java 编译就会自动地调用 toString方法,以便获得这个对象的字符串描述。

对象包装器与自动装箱

有时, 需要将 int 这样的基本类型转换为对象。 所有的基本类型都冇一个与之对应的类。

例如,Integer 类对应基本类型 int。通常, 这些类称为包装器 ( wrapper )。

这些对象包装器类 拥有很明显的名字:Integer、Long、Float、Double、Short、Byte、Character 、Void 和 Boolean (前 6 个类派生于公共的超类 Number)。

从list.add(3); 转换为list.add(Integer.valueOf(3)); 这种方式被称为自动装箱(autoboxing)。反之,则为自动拆箱。

另外, 如果在一个条件表达式中混合使用 Integer 和 Double 类型, Integer 值就会拆箱, 提升为 double, 再装箱为 Double。

最后强调一下,装箱和拆箱是编译器认可的,而不是虚拟机。

枚举类

在比较两个枚举类型的值时, 永远不需要调用 equals, 而直接使用“ = =” 就 可以了。

所有的枚举类型都是 Enum 类的子类。它们继承了这个类的许多方法。其中最有用的一 个是 toString, 这个方法能够返回枚举常量名。

static Enum valueOf(Cl ass enumClass , String name ) 返回指定名字、给定类的枚举常量。

String toString( ) 返回枚举常量名。

int ordinal ( ) 返回枚举常量在 enum 声明中的位置,位置从 0 开始计数。

int compareTo( E other ) 如果枚举常量出现在 Other 之前, 则返回一个负值;如果 this=other,则返回 0; 否则, 返回正值。枚举常量的出现次序在 enum 声明中给出。

反射

反射库( reflection library) 提供了一个非常丰富且精心设计的工具集, 以便编写能够动 态操纵 Java 代码的程序。这项功能被大量地应用于 JavaBeans 中, 它是 Java组件的体系结构 (有关 JavaBeans 的详细内容在卷 II 中阐述)。使用反射, Java 可以支持 Visual Basic 用户习惯 使用的工具。特别是在设计或运行中添加新类时, 能够快速地应用开发工具动态地查询新添 加类的能力。

能够分析类能力的程序称为反射(reflective )。反射机制的功能极其强大,在下面可以看 到, 反射机制可以用来:

在运行时分析类的能力。

在运行时查看对象, 例如, 编写一个 toString 方法供所有类使用。

实现通用的数组操作代码。

还有一个很有用的方法 newlnstance( ), 可以用来动态地创建一个类的实例。

newlnstance方法调用默认的构造器(没有参数的构 造器)初始化新创建的对象。

异常

异常有两种类型: 未检查异常和已检查异常。 对于已检查异常, 编译器将会检查是否提 供了处理器。编译 器不会査看是否为这些错误提供了处理器。

利用反射分析类的能力

在 java.lang.reflect 包中有三个类 Field、 Method 和 Constructor 分别用于描述类的域、 方 法和构造器。 这三个类都有一个叫做 getName 的方法, 用来返回项目的名称。Held 类有一 个 getType 方法, 用来返回描述域所属类型的 Class 对象。Method 和 Constructor 类有能够 报告参数类型的方法,Method 类还有一个可以报告返回类型的方法。

继承设计的技巧

1.将公共操作和域放在超类

这就是为什么将姓名域放在 Person类中,而没有将它放在 Employee 和 Student 类中的原因。

2.不要使用受保护的域

3.使用继承实现“ is-a” 关系

4.除非所有继承的方法都有意义,否则不要使用继承

5.在覆盖方法时,不要改变预期的行为

6.使用多态, 而非类型信息

7.不要过多地使用反射。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值