宠物店
需求:
- 你是宠物店老板,在宠物店中卖各种宠物,比如猫、狗、鸭子、猎豹和鱼等等。
- 所有的宠物都有各自的名字和健康数值。
- 有些宠物还分各种品种,比如狗分为拉布拉多和京巴两个品种。
- 猫和猎豹的叫声一样
- 鱼不会叫
- 当顾客来店里买宠物时,你会让宠物发出温柔的叫声来打动顾客,给顾客显示信息,希望顾客能购买。
要求:
- 根据以上描述,用面向对象思想设计程序,并运用抽象类和接口来编码实现。
分析:
1.对象:
有猫、狗、鸭子、猎豹、鱼、宠物、宠物店。
2.对象具有的属性:
宠物(名字、健康值);狗(品种);宠物店(宠物的数组)
3.对象的行为:
宠物(叫、信息显示)
4.具有的类:
猫、狗、鸭子、猎豹、鱼、宠物店、宠物
1 抽象类和抽象方法
在Java中,当一个类被abstract关键字修饰的时候这个类称为抽象类,当一个类的方法被abstract关键字修饰的时候,该方法称为抽象方法。抽象方法必须定义在抽象方法中。
当一个方法被定义为抽象方法后,意味着该方法不会有具体的实现,而是在抽象类的子类中通过方法的重写进行实现。
1.1抽象版本
代码实现:
/**
* 宠物类:父类
*/
public class Pet {
private String name;//名称
private Integer health;//健康值 0-100表示健康程度
public Pet() {
this("无名氏",80);
}
public Pet(String name, Integer health) {
super();
this.name = name;
this.health = health;
}
/**
* 宠物的叫声,抽象方法
*/
protected void sound();
/**
* 显示信息
* @return
*/
@Override
protected String toString() {
return "名字:" + name + ",健康状况:" + health ;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getHealth() {
return health;
}
public void setHealth(Integer health) {
this.health = health;
}
}
/**
* 猫类
*/
public class Cat extends Pet{
public Cat() {
}
public Cat(String name, Integer health) {
super(name, health);
}
//重写抽象方法
@Override
protected void sound() {
System.out.println("喵喵喵");
}
}
/**
* 鸭子类
*/
public class Duck extends Pet{
public Duck() {
}
public Duck(String name, Integer health) {
super(name, health);
}
//重写抽象方法
@Override
protected void sound() {
System.out.println("嘎嘎嘎");
}
}
/**
* 狗类
*/
public class Dog extends Pet{
//狗类新增的属性
private String breed;
public Dog() {
super();
this.breed = "品种未知";
}
public Dog(String name, Integer health,String breed) {
super(name, health);
this.breed = breed;
}
//重写抽象方法
@Override
protected void sound() {
System.out.println("汪汪汪");
}
@Override
public String toString() {
return super.toString() + ",品种:"+ this.breed;
}
}
/**
* 宠物店
*/
public class PetShop {
//宠物
private static Pet []pets =null;
static {
pets = new Pet[]{
new Dog("大黄",80,"拉布拉多"),
new Dog("富贵",70,"京巴"),
new Dog("招财",80,"拉布拉多"),
new Cat("大咪",90),
new Cat("小咪",80),
new Cat("老咪",90),
new Duck("唐老鸭",60),
new Duck("LIsa",90),
new Cheetah("小宝",80),
new Cheetah("黑豹",90),
new Fish("泡泡",90),
new Fish("泡泡",70),
new Fish("肉肉",60)
};
}
public static void main(String[] args) {
//来顾客了,随机挑选宠物,显示宠物信息
for (int i = 0; i < 5; i++) {
//随机选择宠物
int index = new Random().nextInt(PetShop.pets.length);
Pet pet = pets[index];
//宠物的信息显示
System.out.println(pet.toString());
//宠物的叫声
pet.sound();
}
}
}
测试结果:
名字:富贵,健康状况:70品种:京巴
汪汪汪
名字:招财,健康状况:80品种:拉布拉多
汪汪汪
名字:泡泡,健康状况:70
名字:小咪,健康状况:80
喵喵喵
名字:老咪,健康状况:90
喵喵喵
名字:招财,健康状况:80品种:拉布拉多
汪汪汪
名字:黑豹,健康状况:90
喵喵喵
名字:老咪,健康状况:90
喵喵喵
名字:大黄,健康状况:80品种:拉布拉多
汪汪汪
名字:唐老鸭,健康状况:80
嘎嘎嘎
2 接口
如果抽象类中所有的方法都是抽象方法,就可以使用Java提供的接口来表示,从这个角度讲,接口可以看作是一种特殊的 "抽象类" ,但是采用与抽象类完全不同的语法来表示,两者的设计理念也不同。
接口和抽象类都不能实例化,接口的定义类似于类的定义。语法格式如下:
public interface 接口名{
//接口成员
}
与抽象类一样,使用接口必须通过子类来实现,子类通过implements关键字实现接口,实现接口的语法如下:
public 类名 implements 接口名{
实现方法
普通方法
属性
}
2.1接口版本:
- Pet类提供信息显示的方法
- 定义叫的接口,让猎豹,猫,狗,鸭子实现叫的接口,而鱼不去实现叫的接口
/**
* 宠物类:父类
*/
public abstract class Pet {
private String name;//名称
private Integer health;//健康值 0-100表示健康程度
public Pet() {
this("无名氏",80);
}
public Pet(String name, Integer health) {
super();
this.name = name;
this.health = health;
}
/**
* 信息显示
* @return
*/
@Override
public String toString() {
return "名字:" + name + ",健康状况:" + health ;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getHealth() {
return health;
}
public void setHealth(Integer health) {
this.health = health;
}
}
/**
* 所有喵喵喵叫的子类的适配器
*/
public class SoundAdapter extends Pet implements IShout{
public SoundAdapter(String name, Integer health) {
super(name, health);
}
@Override
public void sound() {
System.out.println("喵喵喵");
}
}
/**
* 猫类
*/
public class Cat extends SoundAdapter{
public Cat(String name, Integer health) {
super(name, health);
}
}
/**
* 狗类
*/
public class Dog extends Pet implements IShout {
//狗类新增的属性
private String breed;
public Dog() {
super();
this.breed = "品种未知";
}
public Dog(String name, Integer health,String breed) {
super(name, health);
this.breed = breed;
}
@Override
public void sound() {
System.out.println("汪汪汪");
}
@Override
public String toString() {
return super.toString() + "品种:"+ this.breed;
}
}
/**
* 鸭子类
*/
public class Duck extends Pet implements IShout{
public Duck() {
}
public Duck(String name, Integer health) {
super(name, health);
}
@Override
public void sound() {
System.out.println("嘎嘎嘎");
}
}
/**
* 鱼
*/
public class Fish extends Pet {
public Fish() {
}
public Fish(String name, Integer health) {
super(name, health);
}
}
/**
* 猎豹类
*/
public class Cheetah extends SoundAdapter {
public Cheetah(String name, Integer health) {
super(name, health);
}
}
public class PetShop {
//宠物
private static Pet []pets =null;
static {
pets = new Pet[]{
new Dog("大黄",80,"拉布拉多"),
new Dog("富贵",70,"京巴"),
new Dog("招财",80,"拉布拉多"),
new Cat("大咪",90),
new Cat("小咪",80),
new Cat("老咪",90),
new Duck("唐老鸭",60),
new Duck("LIsa",90),
new Cheetah("小宝",80),
new Cheetah("黑豹",90),
new Fish("泡泡",90),
new Fish("泡泡",70),
new Fish("肉肉",60)
};
}
public static void main(String[] args) {
//来顾客了,随机挑选宠物,让宠物自我介绍
for (int i = 0; i < 10; i++) {
//随机选择宠物
int index = new Random().nextInt(PetShop.pets.length);
Pet pet = PetShop.pets[index];
//宠物的信息显示
System.out.println(pet.toString());
if(pet instanceof Cat){//instanceof判断一个引用指向的实例 是否是某个类的实例
Cat cat = (Cat)pet;
cat.sound();
}else if(pet instanceof Dog){
Dog dog = (Dog)pet;
dog.sound();
}else if(pet instanceof Duck){
Duck duck = (Duck)pet;
duck.sound();
}else if(pet instanceof Cheetah){
Cheetah cheetah = (Cheetah)pet;
cheetah.sound();
}
}
}
测试结果:
名字:泡泡,健康状况:70
名字:老咪,健康状况:79
喵喵喵
名字:小宝,健康状况:80
喵喵喵
名字:泡泡,健康状况:70
名字:大咪,健康状况:100
喵喵喵
名字:肉肉,健康状况:60
名字:Tom,健康状况:99
嘎嘎嘎
名字:花花,健康状况:98
喵喵喵
名字:中黄,健康状况:90品种:京巴
汪汪汪
名字:肉肉,健康状况:60
