面向对象的一个重要目标就是对代码重用的支持。支持这个目标的一个重要机制就是泛型机制(generic mechanism):如果出去对象的基本类型外,实现方法是相同的,就可以用泛型实现(generic implementation)来描述这种基本功能。在Java 1.5版本以前,Java并不直接支持泛型实现,泛型编程的实现是通过使用继承的一些基本概念来完成的。
1、 使用Object表示泛型
Java中的基本思想就是通过使用像Object这样适当的超类来实现泛型。
public class DSAA0101_MemoryCell
{
private Object storedValue;
public Object read()
{
return storedValue;
}
public void write(Object x)
{
storedValue = x;
}
}
public class DSAA0101_TestMemoryCell
{
public static void main(String[] args)
{
DSAA0101_MemoryCell mc = new DSAA0101_MemoryCell();
mc.write("1105");
String val = (String)mc.read();
System.out.println("Content are: " + val);
}
}
在用这种策略时,要考虑两个细节。第一,为了访问对象的特定方法,必须要强制转换成正确的类型;第二,不能使用基本类型,之用引用类型能与Object相容。
2、 基本类型的包装
Java中的每一个引用类型都和Object相容,但8种基本类型却不能。Java为这8种基本类型中的每一种都提供了一个包装类(wrapper class),每一个包装对象都是不可变的,它存储一种该对象被构建时所设置的原值,并提供一种方法重新得到该值。
public class DSAA0101_WrapperDemo
{
public static void main(String[] args)
{
DSAA0101_MemoryCell mc = new DSAA0101_MemoryCell();
mc.write(new Integer(1105));
Integer wrapperValue = (Integer)mc.read();
int val = wrapperValue.intValue();
System.out.println("Content are: " + val);
}
}
3、 使用接口类型表示泛型
只有在使用Object类中已有的方法能够表示所执行的操作的时候,才能使用Object作为泛型类型来工作。
我们不能直接找出Object的数组中最大元素 – 我们需要更多信息。最简单的想法就是找出Comparable的数组中的最大元素。要确定顺序,可以使用compareTo方法,它对所有的Comparable都必然是现成可用的。
几点忠告。首先,只有实现Comparable接口的对象才能作为Comparable数组的元素被传递。需要比较两个Shape的面积,因此假设Shape实现Comparable接口,Circle、Square和Rectangle都是Shape的子类。
第二,如果Comparable数组中有两个不相容的对象(例如,一个String和一个Shape),那么CompareTo方法将抛出异常,这是我们期望的。
第三,基本类型不能作为Comparable传递,但包装类可以,因为它们实现了Comparable接口。
第四,接口可以不是标准的库接口。
最后,这种方案不是总能行得通。因为有时宣称一个类实现所需要的接口是不可能的。例如,一个类是库中的类,而接口却是用户定义的接口。如果一个类是final类,就不可能扩展它以创建新的类。对这个问题有另外一个解决方案,即function object。
public interface IGetArea
{
double area();
}
public class Shape implements IGetArea, Comparable
{
public double area()
{
return 0.0;
}
public int compareTo(Object obj)
{
Shape shape = (Shape)obj;
if(this.area() - shape.area() > 0)
{
return 1;
}
else if(this.area() - shape.area() < 0)
{
return -1;
}
else
{
return 0;
}
}
}
public class Circle extends Shape
{
private double r;
public Circle(double r)
{
this.r = r;
}
public double area()
{
return Math.PI * r * r;
}
@Override
public String toString()
{
return "Circle";
}
public int compareTo(Object obj)
{
Shape shape = (Shape)obj;
if(this.area() - shape.area() > 0)
{
return 1;
}
else if(this.area() - shape.area() < 0)
{
return -1;
}
else
{
return 0;
}
}
}
public class Square extends Shape
{
private double length;
public Square(double length)
{
this.length = length;
}
public double area()
{
return length * length;
}
@Override
public String toString()
{
return "Square";
}
public int compareTo(Object obj)
{
Shape shape = (Shape)obj;
if(this.area() - shape.area() > 0)
{
return 1;
}
else if(this.area() - shape.area() < 0)
{
return -1;
}
else
{
return 0;
}
}
}
public class Rectangle extends Shape
{
private double length;
private double width;
public Rectangle(double length, double width)
{
this.length = length;
this.width = width;
}
public double area()
{
return length * width;
}
@Override
public String toString()
{
return "Rectangle";
}
public int compareTo(Object obj)
{
Shape shape = (Shape)obj;
if(this.area() - shape.area() > 0)
{
return 1;
}
else if(this.area() - shape.area() < 0)
{
return -1;
}
else
{
return 0;
}
}
}
public class DSAA0102_FindMaxDemo
{
/*
* Returen max item in arr.
* Precondition: arr.length > 0
*/
public static Comparable findMax(Comparable[] arr)
{
int maxIndex = 0;
for(int i = 1; i < arr.length; i++)
{
if(arr[i].compareTo(arr[maxIndex]) > 0)
{
maxIndex = i;
}
}
return arr[maxIndex];
}
public static void main(String[] args)
{
/*
* Test findMax on Shap and String objects
*/
Shape[] sh1 = {new Circle(2.0), new Square(3.0), new Rectangle(13.0, 14.0)};
String[] str1 = {"Joe", "Zeke", "Bill", "Bush"};
System.out.println("Max Shape: " + findMax(sh1));
System.out.println("Max String: " + findMax(str1));
}
}
原文地址:https://www.cnblogs.com/Tom-1103/p/11805105.html