《Data Structure and Algorithm Analysis in Java》中Java语言的重要特点 - 实现泛型构件 pre-Java 5

面向对象的一个重要目标就是对代码重用的支持。支持这个目标的一个重要机制就是泛型机制(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

时间: 2024-08-29 17:24:07

《Data Structure and Algorithm Analysis in Java》中Java语言的重要特点 - 实现泛型构件 pre-Java 5的相关文章

《Data Structure and Algorithm Analysis in Java》第 3 章 - 表

1.抽象数据类型 抽象数据类型(abstract data type,ADT)是带有一组操作的一些对象的集合.在 ADT 的定义中没有地方提到关于这组操作是如何实现的任何解释. Java 类也考虑到 ADT 的实现,不过适当地隐藏了实现的细节.如果由于某种原因需要改变实现的细节,通过仅仅改变执行这些 ADT 操作的例程应该是很容易做到的.这种改变对于程序的其余部分是完全透明的. 对以每种 ADT 并不存在什么法则来告诉我们必须要有哪些操作,这是一个设计决策.错误处理和结构调整(在适当的地方)一般

java中利用反射机制绕开编译器对泛型的类型限制

首先看下面这个例子 public static void main(String[] args) { ArrayList<Integer> al1 = new ArrayList<Integer>(); al1.add(1); ArrayList<String> al2 = new ArrayList<String>(); al2.add("hello"); //int型链表和string型链表,结果为true System.out.pr

资源向导之 &quot;Data structure and Algorithm&quot;

几本神书: 一.最佳入门--DSAA 这门书相关的代码. http://users.cis.fiu.edu/~weiss/dsaa_c2e/files.html 我自己也写了一些. 二.大名鼎鼎的CLRS. MIT Introduction to algorithm http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-006-introduction-to-algorithms-fall-2011/in

[Data Structure] An Algorithm for Matching Delimiters

An important task when processing arithmetic expressions is to mach delimiters. We can use Stack to solve this problem. def is_matched(expr): left='({[' right=')}]' S=ArrayStack() for c in expr: if c in left: S.push(c) elif c in right: if S.is_empty(

23种设计模式介绍以及在Java中的实现

原创不易,转载请注明出处:http://anxpp.com/,谢谢!     文章比较长,读者可以通过顶端的目录选择要了解的模式,然后通过文章右边的按钮快速返回顶部重新选择一个新的模式浏览 博主精心准备了大量的示例代码.文章尽量提供与编程相关的例子,而不是像多数其他介绍的文章一样,提供一些感觉挺滑稽的例子(那样的例子可能看完觉得写得很好,然而还是不会用...). 本文耗费了作者大量时间,还请亲们给个赞O(∩_∩)O~ 也可以通过CTRL+F并输入要了解的模式并跳到对应位置. 文章中的示例源码在g

Java中创建对象的几种方式

Java中创建对象的五种方式: 作为java开发者,我们每天创建很多对象,但是我们通常使用依赖注入的方式管理系统,比如:Spring去创建对象,然而这里有很多创建对象的方法:使用New关键字.使用Class类的newInstance方法.使用Constructor类的newInstance方法.使用Clone方法.使用反序列化. 使用new关键字:这是我们最常见的也是最简单的创建对象的方式,通过这种方式我们还可以调用任意的够赞函数(无参的和有参的).比如:Student student = ne

JAVA中文件的读写 I/O 输入输出流

主要内容 1.编码问题 2.File类的使用 3.RandomAccessFile的使用 4.I/O 输入输出流 编码问题: 1 import java.io.UnsupportedEncodingException; 2 3 public class 编码问题 { 4 public static void main(String[] args) { 5 // 我们项目的默认编码是GBK 6 String s = "测试 ABC"; 7 byte[] byte1 = s.getByte

Java中的NIO基础知识

上一篇介绍了五种NIO模型,本篇将介绍Java中的NIO类库,为学习netty做好铺垫 Java NIO 由3个核心组成,分别是Channels,Buffers,Selectors.本文主要介绍着三个部分. Channel 所有的I/O都从一个Channel开始.通道与流不同,通道是双向的,流是单向的. 即可以从通道中读取数据,也可以写数据到通道里 . 读的话,是从通道读取数据到缓冲区,写的话是从缓冲区写入数据到通道. 四种通道: FileChannel.从文件中读写数据 DatagramCha

Java中出现的异常类型

Java中出现的异常类型     失踪的格式参数异常 java.util.MissingFormatArgumentException异常 错误提示信息: java.util.MissingFormatArgumentException:Format specifier 's' 原因:字符串格式化提供的值的数量少于字符串格式符(%s)的数量 参数:  format - 在格式字符串的语法中描述的格式字符串  args - 格式字符串中的格式说明符引用的参数.如果参数多于格式说明符,则忽略额外的参