天天看点

[J2SE 基础知识]2、抽象类和接口(上)

抽象类和接口

一、抽象类

在类层次结构中,类的位置越高,其定义的抽象程度也就越高。在定义类层次结构中的过程中,有一些类确定了子类的通用的行为和属性,而且这些类不能被实例化用限定符abstract来声明。这些类称为抽象类。

l    抽象类可以包含常规类能够包含的任何东西,包括构造方法,因为子类可能需要继承这种方法。

l    抽象类也可以包含抽象方法,也就是没有实现的方法,而这些方法在子类中被实现。不能在非抽象类中声明抽象方法。

l    如果一个抽象类中除了抽象方法外什么都没有,则最好使用接口。

二、接口

     与抽象类和抽象方法一样,接口也是提供了其他类要实现的行为模板。

使用和实现接口

l    要使用接口,可以在类定义中包含关键字implements

l    包含接口后,必须实现该接口中的所有方法,而不能有选择地实现其中的某些。

l    类实现接口后,子类将继承该接口中的所有方法,并可以覆盖或重载它们。

l    若类继承了一个实现了某一接口的超类,则不必在本类中又implements一次。

l    要在类中使用多个接口,只需要将它们的名称用逗号分开。

使用多个接口时如果两个接口定义了相同的方法,则应注意以下规则:

l    如果两个方法的特征标相同,可以在类中实现一个方法,其定义能够满足两个接口。

l    如果方法的参数列表不同,则是一种简单的方法重载:实现两种方法特征标,分别满足两个接口的需要。

l    如果方法的参数列表相同,但返回值不同,则无法创建一个能够满足两个接口的方法。这时,编译会出错。

创建接口的规定:

l    创建接口要用interface,而不是class。

l    如果接口前没有限定符,则自动被转换为abstract和public的,而且不能在接口内将方法声明为私有的或是保护的。

l    除了方法外,接口还可以包含变量,但它们必须是公有、静态和final的(常量)。或者不使用限定符,这样会自动声明为这些限定,而且变量须赋值。

l    如果声明接口时没有使用pulbic,则接口不会自动将方法转换为公有和抽象的,也不会将常量转换为公有的。而非公有接口的方法和常量也是非公有的,这些方法和常量只能被同一个包中的类和其他接口使用。

l    与类一样,接口也可以属于某个包。接口还可以导入其他包中的接口和类,就像类一样。

l    接口可以继承另一个接口,此时‘子接口’将获得‘超接口’中声明的所有方法定义和常量。这时要使用extends扩展。

l    另外,不同于类,接口可以多重继承,新接口将包含其父接口中的方法和常量。(多继承约束参见本话题之上的一个话题)

三、实例

创建一个网上商店,应用程序Storefront使用了包、访问控制、接口和封装。主要处理两项任务:

l    根据库存量计算每种商品的销售价格;

l    按照销售价格对商品排序;

Item类

package com.prefect.ecommerce;

/**

* 本类实现了Comparable接口,这个接口使得对类的对象进行排序更容易。

* 这个接口只有一个方法compareTo(Object),返回一个整数,功能是比较

* 两个对象:

*      若当前对象应排列在另一个之前,返回-1

*      若当前对象应排列在另一个之后,返回1

*      两个对象相等,则返回0

* */

public class Item implements Comparable

{

        private String id;

        private String name;

        private double retail;

        private int quantity;

        private double price;

        Item(String id,String name,String retail,String quan)

        {

                this.id = id;

                this.name = name;

                this.retail = Double.parseDouble(retail);

                this.quantity = Integer.parseInt(quan);

                if(this.quantity > 400)

                {

                        this.price = this.retail * .5D;                        

                }

                else if(this.quantity > 200)

                        this.price = this.retail * .6D;

                else

                        this.price = this.retail * .7D;

                //对price四舍五入,Math.floor()表示将小数舍入为与之最接近且不大于它的整数

                //并返回double

                price = Math.floor(price * 100 + .5)/100;

        }

        //compareTo()方法需要决定根据哪个实例变量来对对象进行排序,这里根据price

        public int compareTo(Object o)

                Item temp = (Item)o;

                if(this.price < temp.price)

                        return 1;

                else if(this.price > temp.price)

                        return -1;

                return 0;

        public String getId()

                return id;

        public String getName()

                return name;

        public double getPrice()

                return price;

        public int getQuantity()

                return quantity;

        public double getRetail()

                return retail;

Storefont类

*用于管理商店中的商品,每一种商品都是一个Item对象,他们被存储在链表中    

*/

import java.util.Collections;

import java.util.LinkedList;

public class Storefont

        //创建一个链表

        private LinkedList catalog = new LinkedList();

        //将item加入到链表中

        public void addItem(String id, String name, String price, String quant)

                Item it = new Item(id, name, price, quant);

                //在链表中添加对象的方法

                catalog.add(it);

        //返回当前的item,使用索引i来读取他们

        public Item getItem(int i)

                //读取链表中的索引

                return (Item) catalog.get(i);

        //返回链表中的对象数

        public int getSize()

                //链表的大小

                return catalog.size();

        public void sort()

                //此方法对链表和其他数据结果中的对象进行排序,期间将调用对象的

                //comparaTo()方法来确定排序

                Collections.sort(catalog);

}

GiftShop类

public class GiftShop

        public static void main(String[] args)

                Storefont store = new Storefont();

                //添加商品

                store.addItem("C01","MUG","9.99","150");

                store.addItem("C02","LG MUG","12.99","82");

                store.addItem("C03","MOUSEPAD","10.49","800");

                store.addItem("D01","T SHIRT","16.99","90");

                //进行排序

                store.sort();

                //输出排序后的结果

                for(int i = 0 ; i < store.getSize() ; i++)

                        Item show = (Item)store.getItem(i);

                        System.out.println("\nItem ID:" + show.getId()

                                        + "\nName:" + show.getName()

                                        + "\nRetail Price:$" + show.getRetail()

                                        + "\nPrice:$" + show.getPrice()

                                        + "\nQuantity:" + show.getQuantity());

运行结果

Item ID:D01

Name:T SHIRT

Retail Price:$16.99

Price:$11.89

Quantity:90

Item ID:C02

Name:LG MUG

Retail Price:$12.99

Price:$9.09

Quantity:82

Item ID:C01

Name:MUG

Retail Price:$9.99

Price:$6.99

Quantity:150

Item ID:C03

Name:MOUSEPAD

Retail Price:$10.49

Price:$5.25

Quantity:800