Java基本功练习十九(抽象类和接口【抽象类、接口(监听器、克隆、可比较)、包装类、有理数类实现】)

来源:互联网 发布:json返回html标签 编辑:程序博客网 时间:2024/06/04 19:37

在展示范例之前,先介绍一些相关的概念和注意点,这是抽象类和接口的基础预备知识。

在继承的层次结构中,随着每个新子类的出现,类会变的越来越明确和具体。如果从一个子类追溯到父类,类就会变得更通用、更加不明确。类的设计应该确保父类包含子类的共同特征。

有时候,一个父类设计的非常抽象,以至于它没有任何具体的实例。这样的类称为抽象类

抽象类中不实现,只声明的方法称为抽象方法。在方法头中用abstract修饰符表示。在类头使用abstract修饰符表示该类为抽象类。在UML类图中,抽象类和方法的名字用斜体表示。

抽象类和常规类很像,但是不能使用new操作符创建它的实例。抽象方法只有定义而没有实现。它的实现由子类提供。一个包含抽象方法的类必须声明为抽象类。

抽象类的构造方法定义为protected,因为它只被子类使用。创建一个具体子类的实例时,它的父类构造方法被调用以初始化父类中定义的数据域。

关于抽象类的几个注意点:

1)抽象方法不能包含在非抽象类中。如果抽象父类的子类不能实现所有的抽象方法,那么子类必须定义为抽象的。换句话说,在抽象类扩展的非抽象类中,必须实现所有的抽象方法。并且,抽象方法是非静态的。

2)包含抽象对象的类必须是抽象的。但是,可以定义一个不包含抽象方法的抽象类。在这种情况下,不能使用new操作符创建该类的实例。这种类是用来定义新子类的基类的。

3)即使子类的父类是具体的,这个子类也可以是抽象的。

4)子类可以覆盖父类的方法并将它定义为abstract。这是很少见的,但是它在当父类的方法实现在子类中变得不合法时是很有用的。在这种情况下,子类必须定义为abstract。

5)不能使用new操作符从一个抽象类创建一个实例,但是抽象类可以用作一种数据类型。

接口是一种与类相似的结构,只包含常量和抽象方法。它在很多方面都与抽象类很相似,但是它的目的是指明多个对象的共同行为。如,使用正确的接口,可以指明这些对象是可以比较的、可食用的或可克隆的。

Java中,接口被看作是一种特殊的类。就像常规类一样,每个接口都被编译为独立的字节码文件。与抽象类相似,不能使用new操作符创建接口的实例,但是大多数情况下,使用接口或多或少有点像使用抽象类。如可以使用接口作为引用变量的数据类型或类型转换的结果等等。

接口和抽象类的区别

或多或少可以使用和抽象类一样的方式使用接口,但是定义一个接口和定义一个抽象类有所不同,如下表所示:


  Java只允许为类的扩展做单一继承,但是允许使用接口做多重扩展,如下所示的定义是合法的。

接口可以扩展其他接口而不是类。一个类可以扩展它的父类同时实现多个接口 。

所有的类共享同一个根类Object,但是接口没有共同的根。与类类似,接口也可以定义一种类型。一个接口类型的变量可以引用任何实现该接口的类的实例。如果一个类实现了一个接口,那么这个接口就类似于该类的一个父类。可以将接口当作一种数据类型使用,将接口类型的变量转换成他的子类,反过来也可以。


范例一:抽象类的使用范例。

运行效果如图:

实现的源代码如下所示:

package Blog;public class blogTryProject {public static void main(String[] args) {TestChouXiang tcx = new TestChouXiang();tcx.main(args);}}//抽象类测试程序class TestChouXiang{public static void main(String[]args){Rectangle rt = new Rectangle(4,5);System.out.println(rt.toString());System.out.println("Rectangle 的面积为:"+rt.getArea());System.out.println("Rectangle 的周长为:"+rt.getPerimeter());Circle c = new Circle(3);System.out.println(c.toString());System.out.println("Circle 的面积为:"+c.getArea());System.out.println("Circle 的周长为:"+c.getPerimeter());}}//抽象类GeometricObjectabstract class GeometricObject{private String color = "White";private boolean filled;private java.util.Date dateCreated;protected GeometricObject(){dateCreated = new java.util.Date();}protected GeometricObject(String color,boolean filled){dateCreated = new java.util.Date();this.color = color;this.filled = filled;}public String getColor(){return color;}public void setColor(String color){this.color = color;}public void setFilled(boolean filled){this.filled = filled;}public java.util.Date getDateCreated(){return dateCreated;}public String toString(){return "created on "+dateCreated+"\ncolor: "+color+"\t\tfilled: "+filled;}public abstract double getArea();public abstract double getPerimeter();}//矩形类class Rectangle extends GeometricObject{private double width;private double height;public Rectangle(){}public Rectangle(double width,double height){this.width = width;this.height = height;}public Rectangle(double width,double height,String color,boolean filled){this.width = width;this.height = height;setColor(color);setFilled(filled);}public double getWidth(){return width;}public void setWidth(double width){this.width = width;}public double getHeight(){return height;}public void setHeight(double height){this.height = height;}public double getArea(){return width * height;}public double getPerimeter(){return 2 * (width + height);}public String toString(){return super.toString()+"\n宽为:"+getWidth()+"\t\t长为:"+getHeight();}}//圆类class Circle extends GeometricObject{private double radius;public Circle(){}public Circle(double radius){this.radius = radius;}public Circle(double radius,String color,boolean filled){this.radius = radius;setColor(color);//这里不能用this.color = color;因为它是父类的私有数据域,在GeometricObject//类外只能通过访问器和修改器对它进行操作setFilled(filled);}public double getRadius(){return radius;}public void setRadius(double radius){this.radius = radius;}public double getArea(){return radius * radius * Math.PI;}public double getPerimeter() {return 2 * radius * Math.PI;}public double getDiameter(){return 2 * radius;}public String toString(){return super.toString()+"\n半径为: "+radius;}}

范例二:接口的简单范例。

运行效果如图所示:

实现的源代码如下所示:

package Blog;public class blogTryProject {public static void main(String[] args) {TestEdible te = new TestEdible();te.main(args);}}//接口的简单范例interface Edible{public abstract String howToEat();}class TestEdible{public static void main(String[]args){Object[] objects = {new Tiger(),new Chicken(),new Apple(),new Orange()};for(int i = 0;i < objects.length;i++)if(objects[i] instanceof Edible)System.out.println(((Edible)objects[i]).howToEat());}}class Animal{}class Chicken extends Animal implements Edible{public String howToEat(){return "Chicken: Fry it";}}class Tiger extends Animal{}abstract class Fruit implements Edible{}class Apple extends Fruit{public String howToEat(){return "Apple: Make apple cider";}}class Orange extends Fruit{public String howToEat(){return "Orange: Make orange juice";}}

范例三:监听器接口(ActionListener),克隆接口(Cloneable),可比较接口(Comparable)。

ActionListener

运行效果如图所示:

实现的源代码如下所示:

package Blog;import javax.swing.*;public class blogTryProject {public static void main(String[] args) {HandleEvent he = new HandleEvent();he.main(args);}}//ActionListener监听器接口class HandleEvent extends JFrame{public HandleEvent(){JButton jbtOk = new JButton("Ok");JButton jbtCancel = new JButton("Cancel");JPanel p = new JPanel();p.add(jbtOk);p.add(jbtCancel);add(p);OkListenerClass listener1 = new OkListenerClass();CancelListenerClass listener2 = new CancelListenerClass();//条件二:使用source.addActionListener(listener)注册源对象jbtOk.addActionListener(listener1);jbtCancel.addActionListener(listener2);}public static void main(String[]args){JFrame frame = new HandleEvent();frame.setTitle("Handle Event");frame.setSize(200, 150);frame.setLocation(200, 100);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);}}//条件一:使得OkListenerClass成为监听器类的实例,并实现其方法class OkListenerClass implements java.awt.event.ActionListener{//事件actionPerformed方法的实现public void actionPerformed(java.awt.event.ActionEvent e){System.out.println("Ok button clicked");}}class CancelListenerClass implements java.awt.event.ActionListener{public void actionPerformed(java.awt.event.ActionEvent e){System.out.println("Cancel button clicked");}}
Cloneable(注意克隆不成功会有异常抛出,可参考《Java基本功练习十八》)

运行效果如图所示:

实现的源代码如下所示:

package Blog;public class blogTryProject {public static void main(String[] args) throws CloneNotSupportedException {House house = new House(12,89);house.main(args);}}//Cloneable接口范例class House implements Cloneable,Comparable{private int id;private double area;private java.util.Date whenBuilt;public House(int id,double area){this.id = id;this.area = area;whenBuilt = new java.util.Date();}public int getId(){return id;}public double getArea(){return area;}public java.util.Date getWhenBuilt(){return whenBuilt;}//覆盖Object中保护类型的clone()方法,并增强其可见性为publicpublic Object clone() throws CloneNotSupportedException{return super.clone();}public int compareTo(Object o){if(area > ((House)o).area)return 1;else if(area < ((House)o).area)return -1;elsereturn 0;}public String toString(){return "House的信息,ID为:"+id+"\t面积为:"+area;}public boolean equals(Object o){if(id == ((House)o).id && area == ((House)o).area)return true;elsereturn false;}public static void main(String[]args) throws CloneNotSupportedException{House house1 = new House(502, 123);House house2 = new House(503, 223);House house3 = (House)house1.clone();System.out.println("house1的信息为:"+house1.toString());System.out.println("house2的信息为:"+house2.toString());System.out.println("house3的信息为:"+house3.toString());System.out.println("house1 与 house2 的面积大小比较:"+house1.compareTo(house2));System.out.println("house1 与 house3 是否内容相同? "+house1.equals(house3));System.out.println("house1 与 house3 是否引用变量相同? "+(house1 == house3));}}
Comparable

运行效果如图所示:

实现的源代码如下所示:

package Blog;public class blogTryProject {public static void main(String[] args){TestComparableRectangle tcr = new TestComparableRectangle();tcr.main(args);}}//Comparable接口实现范例/*Comparable的接口定义如下package java.lang;public interface Comparable{  public int compareTo(Object o);}*/class ComparableRectangle extends Rectangle implements Comparable{//构造函数public ComparableRectangle(double width,double height){super(width,height);}//Comparable接口的实现public int compareTo(Object o){if(getArea() > ((ComparableRectangle)o).getArea())return 1;else if(getArea() < ((ComparableRectangle)o).getArea())return -1;elsereturn 0;}//利用接口新定义一个比较两个矩形面积的静态方法public static Comparable max(Comparable o1,Comparable o2){if(o1.compareTo(o2) > 0)return o1;elsereturn o2;}}//测试Comparable接口程序class TestComparableRectangle{public static void main(String[]args){ComparableRectangle tcr1 = new ComparableRectangle(2, 5);ComparableRectangle tcr2 = new ComparableRectangle(3, 6);System.out.println("\nComparable接口演示范例");System.out.println("两个矩形的信息如下");System.out.println(tcr1.toString());System.out.println(tcr2.toString());System.out.println("tcr1 和 tcr2 比较结果为:"+tcr1.compareTo(tcr2));System.out.println("面积大者的信息如下\n"+tcr1.max(tcr1, tcr2));}}//矩形类class Rectangle extends GeometricObject{private double width;private double height;public Rectangle(){}public Rectangle(double width,double height){this.width = width;this.height = height;}public Rectangle(double width,double height,String color,boolean filled){this.width = width;this.height = height;setColor(color);setFilled(filled);}public double getWidth(){return width;}public void setWidth(double width){this.width = width;}public double getHeight(){return height;}public void setHeight(double height){this.height = height;}public double getArea(){return width * height;}public double getPerimeter(){return 2 * (width + height);}public String toString(){return super.toString()+"\n宽为:"+getWidth()+"\t\t长为:"+getHeight();}}//抽象类GeometricObjectabstract class GeometricObject{private String color = "White";private boolean filled;private java.util.Date dateCreated;protected GeometricObject(){dateCreated = new java.util.Date();}protected GeometricObject(String color,boolean filled){dateCreated = new java.util.Date();this.color = color;this.filled = filled;}public String getColor(){return color;}public void setColor(String color){this.color = color;}public void setFilled(boolean filled){this.filled = filled;}public java.util.Date getDateCreated(){return dateCreated;}public String toString(){return "created on "+dateCreated+"\ncolor: "+color+"\t\tfilled: "+filled;}public abstract double getArea();public abstract double getPerimeter();}

范例四:包装类范例。Java提供一个方便的办法,将基本数据类型并入对象或包装成对象,称为包装类

运行效果如图所示:

实现的源代码如下所示:

package Blog;public class blogTryProject {public static void main(String[] args){GenericSort gc = new GenericSort();gc.main(args);}}//对象数组排序范例class GenericSort{public static void main(String[]args){System.out.println("对象数组排序范例");Integer[] intArray = {new Integer(2),new Integer(4),new Integer(3)};Double[] doubleArray = {new Double(3.4),new Double(1.3),new Double(-22.1)};Character[] charArray = {new Character('a'),new Character('J'),new Character('r')};String[] stringArray = {"Tom","John","Fred"};sort(intArray);sort(doubleArray);sort(charArray);sort(stringArray);System.out.println("Sorted Integer objects:");printList(intArray);System.out.println("Sorted Double objects:");printList(doubleArray);System.out.println("Sorted Character objects:");printList(charArray);System.out.println("Sorted String objects:");printList(stringArray);}public static void sort(Comparable[] list){Comparable currentMin;int currentMinIndex;for(int i = 0;i < list.length - 1;i++){currentMin = list[i];currentMinIndex = i;for(int j = i + 1;j < list.length;j++){if(currentMin.compareTo(list[j]) > 0){currentMin = list[j];currentMinIndex = j;}}if(currentMinIndex != i){list[currentMinIndex] = list[i];list[i] = currentMin;}}}public static void printList(Object[] list){for(int i = 0;i < list.length;i++)System.out.print(list[i]+" ");System.out.println();}}

范例五:有理数类的加减乘除实现。

运行效果如图所示:

实现的源代码如下所示:

package Blog;public class blogTryProject {public static void main(String[] args){TestRational tr = new TestRational();tr.main(args);}}//有理数类测试class TestRational{public static void main(String[]args){Rational r1 = new Rational(4,2);Rational r2 = new Rational(2,3);System.out.println(r1+" + "+r2+" = "+r1.add(r2));System.out.println(r1+" - "+r2+" = "+r1.subtract(r2));System.out.println(r1+" * "+r2+" = "+r1.multiply(r2));System.out.println(r1+" / "+r2+" = "+r1.divide(r2));System.out.println(r2+" is "+r2.doubleValue());}}//有理数类实现class Rational extends Number implements Comparable{private long numerator = 0;private long denominator = 1;public Rational(){this(0,1);}public Rational(long numerator,long denominator){long gcd = gcd(numerator,denominator);this.numerator = ((denominator > 0) ? 1 : -1) * numerator / gcd;this.denominator = Math.abs(denominator) / gcd;}private static long gcd(long n,long d){long n1 = Math.abs(n);long n2 = Math.abs(d);int gcd = 1;for(int k = 1;k <= n1 && k <= n2;k++){if(n1 % k == 0 && n2 % k == 0)gcd = k;}return gcd;}public long getNumerator(){return numerator;}public long getDenominator(){return denominator;}public Rational add(Rational secondRational){long n = numerator * secondRational.getDenominator() +denominator * secondRational.getNumerator();long d = denominator * secondRational.getDenominator();return new Rational(n,d);}public Rational subtract(Rational secondRational){long n = numerator * secondRational.getDenominator() -denominator * secondRational.getNumerator();long d = denominator * secondRational.getDenominator();return new Rational(n,d);}public Rational multiply(Rational secondRational){long n = numerator * secondRational.getNumerator();long d = denominator * secondRational.getDenominator();return new Rational(n,d);}public Rational divide(Rational secondRational){long n = numerator * secondRational.getDenominator();long d = denominator * secondRational.numerator;return new Rational(n,d);}public String toString(){if(denominator == 1)return numerator +"";elsereturn numerator+"/"+denominator;}public boolean equals(Object parm1){if((this.subtract((Rational)(parm1))).getNumerator() == 0)return true;elsereturn false;}public int intValue(){return (int)doubleValue();}public float floatValue(){return (float)doubleValue();}public double doubleValue(){return numerator * 1.0 / denominator;}public long longValue(){return (long)doubleValue();}public int compareTo(Object o){if((this.subtract((Rational)o)).getNumerator() > 0)return 1;else if((this.subtract((Rational)o)).getNumerator() < 0)return -1;elsereturn 0;}}

范例六:接口和抽象类简单实例的实现对比。

运行效果如图所示:

实现的源代码如下所示:

package Blog;public class blogTryProject {public static void main(String[] args){ChouXiangAnimal cxa = new ChouXiangAnimal();cxa.main(args);JieKouAnimal jka = new JieKouAnimal();jka.main(args);}}//接口和抽象类的优劣比较//抽象类实现的方式class ChouXiangAnimal{public static void main(String[]args){//抽象类实现AnimalSystem.out.println("抽象类实现Animal");NewAnimal animal = new NewChicken();eat(animal);animal = new Duck();eat(animal);}public static void eat(NewAnimal animal){System.out.println(animal.howToEat());}}abstract class NewAnimal{public abstract String howToEat();}class NewChicken extends NewAnimal{public String howToEat(){return "NewChicken: Fry it";}}class Duck extends NewAnimal{public String howToEat(){return "Duck: Roast it";}}//接口实现方式class JieKouAnimal{public static void main(String[]args){//接口实现的AnimalSystem.out.println("接口实现的Animal");NewEdible stuff = new NewChicken1();eat(stuff);stuff = new Duck1();eat(stuff);stuff = new Broccoli();eat(stuff);}public static void eat(NewEdible stuff){System.out.println(stuff.howToEat());}}interface NewEdible{public String howToEat();}class NewChicken1 implements NewEdible{public String howToEat(){return "NewChicken1: Fry it";}}class Duck1 implements NewEdible{public String howToEat(){return "Duck1: Fry it";}}class Broccoli implements NewEdible{public String howToEat(){return "Broccoli: Stir-fry it";}}

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 有生产日期的赠品在超市过期怎么办 6年免检车辆逾期未年检怎么办 行驶证检验有效期过期2年怎么办 骑摩托车忘带驾驶证和行驶证怎么办 驾驶证逾期未审验怎么办有什么后果 车祸至人腿部骨折沒钱偿还的怎么办 我有c4驾驶证想办c3怎么办 驾驶证和行驶证被交警扣了怎么办 行驶证被交警弄丢了怎么办 没带行驶证让警察发现怎么办 首尔转机换票换乘怎么办过境签证 驾驶证约考帐号与登密码丢失怎么办 考驾照的时候预约密码忘了怎么办 考驾照的预约密码忘了怎么办 摩托车不能挂档不能摘挡了怎么办 身份证丢失了派出所不给挂失怎么办 快递员在中午还送货夏天怎么办啊 驾照一个记分周期扣满12分怎么办 佛山南海车管所怎么办替人消分流程 福州快处中心几流程要怎么办 被对方追尾了对方只有交强险怎么办 摩托车行驶证年检过期一年半怎么办 户口迁到杭州了身份证掉了怎么办 户口已迁至外面要补办结婚证怎么办 汽车年检时间过了1个月怎么办 户口在老家在北京工作怎么办招工 报考驾照时手机号留错了怎么办 合肥驾照换证体检没过怎么办 驾驶证记分周期到了违章未消怎么办 驾照被扣科目一过期没考怎么办 驾驶证暂扣过了换证日期怎么办? 考驾照科目二身份证丢了怎么办 驾照科目一考试身份证丢了怎么办 换驾驶证名下有车辆脱审怎么办 交警把驾驶证和行车证扣了怎么办 连续两天驾照都是扣12分怎么办? 交警开的电动车罚单丢了怎么办 驾驶证b证体检报告拖期怎么办 在中国把美国护照弄丢了怎么办 拿了驾照两年了不敢上高速怎么办 我要移民过香港大陆的驾驶证怎么办