- super并不是一个对象的引用,不能将super赋给另一个对象变量,它只是一个指示编译器调用超类方法的特殊关键字。
this: 1. 引用隐式参数 2. 调用该类其他的构造器。
super: 1.调用超类的方法 2. 调用超类的构造器。
继承关系--“is-a”:可以表述为置换法则
表明程序中出现超类对象的任何地方都可以用子类对象置换。
如子类对象赋给超类变量: Employee e; e = new Manager(...);
对象变量是多态的:
一个对象变量可以指示多种实际类型的现象。
如:一个Employee 变量既可以引用一个Employee 对象也可以引用一个Manager对象。
示例:
Manager boss = new Manager(’angus',5000);
boss.setBonus(5000);
Employee[] staff = new Employee[2];
将经理和雇员都放到数组中
staff[0]=boss;
staff[1]=new Employee('lallal', 5000);
输出每个人的薪水
for(Employee e: staff)
syso...
如下:
angus 10000
lallal 5000
可见staff[0]和staff[1]分别是对Manager和Employee对象的引用,而编译器都将他们看作Employee对象。
在对staff[0]进行调用时,只能调用从超类(Employee)继承或覆盖来的方法。
如果一个方法没有被覆盖并且很短,编译器就能够对他进行优化处理。
例如:内联调用e.getName()将被替换为访问e.name域。
判断两个对象是否具有相同的引用
编写完美的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是否属于同一个类。用getClass或者instanceof检测。
5)将otherObject转换为相应的类类型变量:className other = (className)otherObject;
6)现在开始对所有需要比较的域进行比较:
使用==比较基本类型域
使用equals比较对象域
如果重新定义equals方法就必须重新定义hasCode方法
hasCode方法应该返回一个整型数值,并合理的组合实例域的散列码,以便能够让各个不同的对象产生的散列码更加均匀。
需要使用在org.omg.CORBA包中定义的持有者(holder)类型,包括IntHolder、BooleanHolder等。
每个持有者类型都包含一个公共域值,通过它可以访问存储在其中的值:
public static void triple(IntHolder x){
x.value = 3*x.value;
}
利用...实现,如下计算若干个数值的最大值:
public static double max(double... values)
{
double largest = Double.NEGATIVE_INFINITY;
for(double v: values)
if(v>largest)
largest = v;
return largest;
}
- 获取class类对象的方法,Class类为保存运行时类型信息的类。
一、使用getClass方法
Employee employee = new Employee("mary", 10000);
Class c1 = e.getClass();
二、调用静态方法forName获得类名对应的Class对象:
String className = "java.util.Random";
Class c2 = Class.forName(className);
三、如果T是任意的Java类型,T.class将代表匹配的类的对象。
Class c3 = int.class
作用:
1. 在运行时分析类的能力
通过java.lang.reflect包中的类得到有关类的信息,包括类的域、方法、构造器的相关信息。
2. 在运行时查看对象(运行时使用反射分析对象),例如,编写一个toString方法供所有类使用。
在前面获得了任意对象的数据域名称和类型之后:
获得对应的Class对象
通过Class对象调用GetDeclareFields
这里可以进一步查看数据域的实际内容
Employee mary = new Employee("mary", 10000);
Class c1 = mary.getClass();
Field f = c1.getDeclaredField("name");
f.setAccessible(true); // 这样可使反射机制不受限于访问控制,可以读取私有域的值。
Object vObject = f.get(mary);
3. 实现通用的数组操作代码
Java.lang.reflect包中的Array类允许动态的创建数组。
如要扩展已经填满的数组。
Employee[] a = new Employee[100];
...
// array is full
a = Arrays.copyOf(a,2*a.length)
接下来编写一个通用的方法实现扩展。
1)首先获得a数组堵塞类对象
2)确认他是一个数组
3)使用class类的getComponentType方法确定数组对应得类型
代码如下:
public static Object goodCopyOf(Object a, int newLength)
{
Class c1 = a.getClass();
if(!c1.isArray())
return null;
Class componentType = c1.getComponentType();
int length = Array.getLength(a);
Object newArray = Array.newInstance(componentType, newLength);
System.arraycopy(a,0,newArray,0,Math.min(length,newLength));
return newArray;
}
4. 利用method对象(这个对象很像c++中的函数指针),调用任意方法。
通过调用getDeclareMethods方法,可以得到声明得方法对象数组。