Java实验-宠物商店(链表与接口的使用)

实验目的:
(1) 掌握接口的概念和语法,并能够应用于实际。
(2) 利用实验6-1 LinkedList 实现复杂应用。
基本要求:
本题要求实现宠物商店的宠物上架、下架、查询等操作。要求用链表存储宠物商店中
的宠物。因此,本选题需要在实验 6-1 中实现的链表类“实验 61.LinkedList ”和“实验
61.Node ”。在本程序中,最重要的是定义宠物标准(定义一个宠物接口 Pet ),进入宠物商
店销售的所有宠物(如 Cat 类、 Dog 类、 Fish 类)都需要实现这个标准(即实现接口 Pet )。
根据以上原则,给出了图 6.2 所示的类图( 图中的虚线三角形箭头表示实现接口,实线普
通箭头表示关联 (Association) 关系 )。

6.1Node类
package 实验6;

public class Node{
    Object data;
    Node next;

    public Node(Object data){
        this.data = data;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node{" +
                "data=" + data +
                '}';
   }
}

(1) 定义宠物接口实验 62.Pet
这个接口是宠物商店可处理的宠物标准。宠物商店并不关心具体的宠物是什么,只
关心一点:只要是实现了标准接口的宠物,就可以进入宠物商店,并能够通过宠物商店
进行各种操作。宠物接口 Pet 的定义如下:
package 实验 62;
interface Pet {
public String getName();
public int getAge();
}
interface Pet{
    public String getName();
    public int getAge();
}

(2) 定义 LinkedList
具体要求见实验 6-1

 

package 实验6;

public class LinkedList {
    private Node head;
    private int size;
    public LinkedList(){
        this.head = null;
        this.size = 0;
    }

    public void add(Object data){
        Node node = new Node(data);
        if(head == null)
            head = node;
        else{
            Node tmp = head;
            while(tmp.getNext()!=null)
                tmp = tmp.getNext();
            tmp.setNext(node);
        }
    }
//删除链表元素
    public boolean remove(Object data){
        //在链表中删除值为 data 的节点。若删除成功,返
        //回 true;否则,返回 false。
        if (head == null) {
            System.out.println("无元素可删除");
            return false;
        }
        while (head != null && head.equals(data)) {
            head = head.next;
        }
        //上面已经对头节点的判别是否要进行删除
        //所以要对头结点的下一个结点进行判别
        Node tmp = head;
        while (tmp != null && tmp.next != null) {
            if (tmp.next.equals(data)) {
                tmp.next = tmp.next.next;
            }
        }
        return false;
    }
//查找为data的节点
    public Node search(Object data){
        Node tmp = head;
        while(tmp!=null){
            if(tmp.equals(data)){
                return tmp.getNext();
            }else
                tmp = tmp.next;
        }
        return null;
    }
//在引用 previous 指向的节点后插入一个值为 data
//的节点。若插入成功,返回 true;否则,返回 false
    //虚拟头结点链表插入
    public boolean insertAfter(Node previous,Object data){
        Node tmp = new Node(null);
        Node dNode=new Node(data);
        Node tmp1=tmp;//指向虚拟头结点
        while(tmp1.next!=null){
            if(tmp1.next.equals(data)){
                dNode.next=tmp1.next;
                tmp1.next=dNode;
                return true;
            }
            else
                tmp1=tmp1.next;
        }
        return false;
    }
//寻找结点
    public Node get(int index){
       Node p = head;
       Node tmp =head;
       int count = 0;
       int num = index;
       while(p!=null){
           p = p.next;
           count++;
           if(num<1){
               tmp = tmp.next;
           }
           num--;
       }
       if(count<index)
           return null;
       return tmp;
    }

    //将 node 引用节点的内容改为 data。若修改成功,
    //返回 true;否则,返回 false。
    public boolean set(Node node, Object data) {
        Node tmp = head;
        if (tmp == null)
            return false;
        while (tmp.getNext() != null) {
            if (tmp == node) {
                tmp.setData(data);
                return true;
            }
            else
                tmp =tmp.getNext();
        }
        return false;
    }

    public int size(){
        return this.size;
    }

}

(3) 定义宠物商店类实验 62.PetShop
宠物商店所售卖的宠物数量不定,因此要用链表( LinkedList )对象保存多个宠物。
同时宠物商店能够售卖的宠物必须是具有宠物特征(比如具有名字和年龄)和行为(比
如告知名字或年龄)的一切动物,因此在上架(添加)、卖出(删除)宠物时,接收的参

数都应是Pet接口类型

提示 :在宠物商店类中,先定义一个 LinkedList 类变量 pets ,并实例化。
package 实验 62;
import 实验 61.*;
public class PetShop { // 一个宠物商店要保存多个宠物信息
private LinkedList pets = new LinkedList(); // 用链表保存宠物信息
public void add(Pet pet) { // 新宠物上架操作,以接口对象为参数!
pets.add(pet);
}
public boolean delete(Pet pet) { // 宠物下架操作,以接口对象为参数!
}
public Pet get(int index){
//pets.get() 返回 Node 节点, Node 节点的 getData() 返回 Object ,该 Object 就是 Pet
return (Pet)( pets.get(index).getData() );
}
}
package Exp6;
import 实验6.*;

public class PetShop {
    private LinkedList pets=new LinkedList();
    public void add(Pet pet){//上架
        pets.add(pet);
    }

    public void delete(Pet pet) {
        this.pets.remove(pet);
    }

    public Pet get(int index){
        return (Pet)(pets.get(index).getData());
    }

    public int size(){
        return this.pets.size();
    }
}

(4) 定义宠物猫子类实验 62.Cat
要求 Cat 类实现接口 Pet 。要求 Cat 类有两个私有属性 name age Cat 类中除了
getName() get getAge( ) 方法外,还要求为其实现 3 public 方法,关于这 3 个方法的
要求如表 6.4 所示。 Cat 类的类图如图 6.3 所示。为了简洁起见,在图 6.3 所示的 Cat
图中省略了 getName() 方法和 getAge( ) 方法

class Cat implements Pet{
    private String name;
    private int age;

    public Cat(String name,int age){
        this.name=name;
        this.age=age;
    }

    @Override
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "Name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public boolean equal(Object obj){
        if(this==obj){
            return true;
        }
        if(obj==null){
            return false;
        }
        if(!(obj instanceof Cat)){
            return false;
        }
        if(obj!=null && obj.getClass()==Cat.class){
            Cat cat = (Cat)obj;
            return (this.name.equals(cat.name) && this.age==getAge());
        }
        return false;
    }
}

(5) 定义宠物狗子类实验 62.Dog
要求 Dog 类实现接口 Pet 。要求 Dog 类有两个私有属性 name age Dog 类中除了
getName() get getAge( ) 方法外,还要求为其要求实现 3 public 方法,对这 3 个方法
的要求,与表 6.4 中对 Cat 类中方法的要求类似,因此不再赘述。 Dog 类的类图如图 6.4
所示。

class Dog implements Pet{
    private String name;
    private int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                '}';
    }

    public boolean equal(Object obj){
        if(this==obj){
            return true;
        }
        if(obj==null){
            return false;
        }
        if(!(obj instanceof Cat)){
            return false;
        }
        if(obj!=null && obj.getClass()==Dog.class){
            Dog dog = (Dog)obj;
            return (this.name.equals(dog.name) && this.age==getAge());
        }
        return false;
    }
}
(6) 编写测试类实验 62.Test 。要求在测试类的主方法中,完成如下动作:
① 定义一个宠物商店类变量 shop ,并实例化;
② 在宠物商店 shop 中添加 1 岁的 波斯猫
③ 在宠物商店 shop 中添加 2 岁的 橘猫
④ 在宠物商店 shop 中添加 1 岁的 折耳猫
⑤ 在宠物商店 shop 中添加 1 岁的 柯基犬
⑥ 在宠物商店 shop 中添加 2 岁的 波尔多 (注:波尔多是一种狗名字);
⑦ 显示宠物商店 shop 中所有宠物;
⑧ 删除宠物商店 shop 2 岁的 橘猫
⑨ 显示宠物商店 shop 中所有宠物;
通过运行结果可以发现,由于本程序是面向接口的编程,所以返回的结果中即包含了
Cat 类对象,也包含了 Dog 类对象。
package Exp6;

public class Test {
    public static void main(String[] args) {
        PetShop shop = new PetShop();
        shop.add(new Cat("波斯猫",1));
        shop.add(new Cat("橘猫",2));
        shop.add(new Cat("折耳猫",1));
        shop.add(new Dog("柯基犬",1));
        shop.add(new Dog("波尔多",2));
        shop.delete(new Cat("橘猫",1));
        shop.delete(new Cat("波斯猫",1));
    }
}

所有代码总结:

LinkedList.java

package 实验6;

public class LinkedList {
    private Node head;
    private int size;
    public LinkedList(){
        this.head = null;
        this.size = 0;
    }

    public void add(Object data){
        Node node = new Node(data);
        if(head == null)
            head = node;
        else{
            Node tmp = head;
            while(tmp.getNext()!=null)
                tmp = tmp.getNext();
            tmp.setNext(node);
        }
    }
//删除链表元素
    public boolean remove(Object data){
        //在链表中删除值为 data 的节点。若删除成功,返
        //回 true;否则,返回 false。
        if (head == null) {
            System.out.println("无元素可删除");
            return false;
        }
        while (head != null && head.equals(data)) {
            head = head.next;
        }
        //上面已经对头节点的判别是否要进行删除
        //所以要对头结点的下一个结点进行判别
        Node tmp = head;
        while (tmp != null && tmp.next != null) {
            if (tmp.next.equals(data)) {
                tmp.next = tmp.next.next;
            }
        }
        return false;
    }
//查找为data的节点
    public Node search(Object data){
        Node tmp = head;
        while(tmp!=null){
            if(tmp.equals(data)){
                return tmp.getNext();
            }else
                tmp = tmp.next;
        }
        return null;
    }
//在引用 previous 指向的节点后插入一个值为 data
//的节点。若插入成功,返回 true;否则,返回 false
    //虚拟头结点链表插入
    public boolean insertAfter(Node previous,Object data){
        Node tmp = new Node(null);
        Node dNode=new Node(data);
        Node tmp1=tmp;//指向虚拟头结点
        while(tmp1.next!=null){
            if(tmp1.next.equals(data)){
                dNode.next=tmp1.next;
                tmp1.next=dNode;
                return true;
            }
            else
                tmp1=tmp1.next;
        }
        return false;
    }
//寻找结点
    public Node get(int index){
       Node p = head;
       Node tmp =head;
       int count = 0;
       int num = index;
       while(p!=null){
           p = p.next;
           count++;
           if(num<1){
               tmp = tmp.next;
           }
           num--;
       }
       if(count<index)
           return null;
       return tmp;
    }

    //将 node 引用节点的内容改为 data。若修改成功,
    //返回 true;否则,返回 false。
    public boolean set(Node node, Object data) {
        Node tmp = head;
        if (tmp == null)
            return false;
        while (tmp.getNext() != null) {
            if (tmp == node) {
                tmp.setData(data);
                return true;
            }
            else
                tmp =tmp.getNext();
        }
        return false;
    }

    public int size(){
        return this.size;
    }

}

Node.java

package 实验6;

public class Node{
    Object data;
    Node next;

    public Node(Object data){
        this.data = data;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node{" +
                "data=" + data +
                '}';
   }
}

宠物商店.java

package Exp6;
import java.util.*;

interface Pet{
    public String getName();
    public int getAge();
}

 class Cat implements Pet{
    private String name;
    private int age;

    public Cat(String name,int age){
        this.name=name;
        this.age=age;
    }

    @Override
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Cat{" +
                "Name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public boolean equal(Object obj){
        if(this==obj){
            return true;
        }
        if(obj==null){
            return false;
        }
        if(!(obj instanceof Cat)){
            return false;
        }
        if(obj!=null && obj.getClass()==Cat.class){
            Cat cat = (Cat)obj;
            return (this.name.equals(cat.name) && this.age==getAge());
        }
        return false;
    }
}

class Dog implements Pet{
    private String name;
    private int age;

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                '}';
    }

    public boolean equal(Object obj){
        if(this==obj){
            return true;
        }
        if(obj==null){
            return false;
        }
        if(!(obj instanceof Cat)){
            return false;
        }
        if(obj!=null && obj.getClass()==Dog.class){
            Dog dog = (Dog)obj;
            return (this.name.equals(dog.name) && this.age==getAge());
        }
        return false;
    }
}

Petshop.java

package Exp6;
import 实验6.*;

public class PetShop {
    private LinkedList pets=new LinkedList();
    public void add(Pet pet){//上架
        pets.add(pet);
    }

    public void delete(Pet pet) {
        this.pets.remove(pet);
    }

    public Pet get(int index){
        return (Pet)(pets.get(index).getData());
    }

    public int size(){
        return this.pets.size();
    }
}

Test.java

package Exp6;

public class Test {
    public static void main(String[] args) {
        PetShop shop = new PetShop();
        shop.add(new Cat("波斯猫",1));
        shop.add(new Cat("橘猫",2));
        shop.add(new Cat("折耳猫",1));
        shop.add(new Dog("柯基犬",1));
        shop.add(new Dog("波尔多",2));
        shop.delete(new Cat("橘猫",1));
        shop.delete(new Cat("波斯猫",1));
    }
}


版权声明:本文为m0_52647215原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。