测试类:
package cn.jbit.epettest;
import java.util.Scanner;
import cn.jbit.epetshop.Dog;
import cn.jbit.epetshop.Penguin;
import cn.jbit.epetshop.Pet;
public class EpetShopTest {
/**
* @param args
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.println("欢迎您来到宠物店!");
System.out.print("请输入要领养宠物的名字:");
String name = input.next(); // 宠物名称
System.out.print("请选择要领养的宠物类型:(1、狗狗 2、企鹅)");
String type = input.next(); // 宠物类型
Pet pet = null; // 定义 一个宠物对象
if (type.equals("1")) {
System.out.print("请选择狗狗的品种:(1、聪明的拉布拉多犬 2、酷酷的雪娜瑞)");
String choiceStrain = input.next(); // 选择宠物类型
String strain = null; // 宠物品种
if (choiceStrain.equals("1")) {
strain = "聪明的拉布拉多犬";
} else {
strain = "酷酷的雪娜瑞";
}
// 创建一个宠物狗狗对象
pet = new Dog(name, 100, 0, strain);
} else if (type.equals("2")) {
System.out.print("请选择企鹅的性别:(1、Q仔 2、Q妹)");
String choiceSex = input.next(); // 选择宠物性别
String sex = null; // 宠物性别
if (choiceSex.equals("1")) {
sex = Penguin.SEX_MALE;
} else {
sex = Penguin.SEX_FEMALE;
}
// 创建一个宠物企鹅对象
pet = new Penguin(name, 100, 0, sex);
}
// 调用输出信息方法
pet.print();
}
}
实体类:
package cn.jbit.epetshop;
/**
* 宠物类
*
* @author chaoyi
* @2013-10-17 上午09:25:09
*/
public abstract class Pet {
/**
* 无参构造函数
*/
public Pet() {
}
/**
* 带参构造函数
*
* @param name
* 昵称
* @param health
* 健康值
* @param love
* 亲密度
*/
public Pet(String name, int health, int love) {
this.setName(name);
this.setHealth(health);
this.setLove(love);
}
private String name; // 昵称
/**
* 读取昵称
*
* @return 昵称
*/
public String getName() {
return name;
}
/**
* 指定昵称
*
* @param name
* 昵称
*/
public void setName(String name) {
this.name = name;
}
private int health = 100; // 健康值
/**
* 读取健康值
*
* @return 健康值
*/
public int getHealth() {
return health;
}
/**
* 指定健康值
*
* @param health
* 健康值
*/
public void setHealth(int health) {
if (health >= 0 && health <= 100) {
this.health = health;
} else {
health = 40;
System.out.println("健康值应该在0~100之间,默认值是40");
}
}
private int love = 0; // 亲密度
/**
* 读取亲密度
*
* @return 亲密度
*/
public int getLove() {
return love;
}
/**
* 指定亲密度
*
* @param love
* 亲密度
*/
public void setLove(int love) {
this.love = love;
}
/**
* 输出信息
*/
public abstract void print();
}
package cn.jbit.epetshop;
/**
* 宠物狗狗类
*
* @author Administrator
*
*/
public class Dog extends Pet {
private String strain; // 品种
/**
* 读取品种
*
* @return 品种
*/
public String getStrain() {
return strain;
}
/**
* 指定品种
*
* @param love
* 品种
*/
public void setStrain(String strain) {
this.strain = strain;
}
/**
* 无参构造函数
*/
public Dog() {
}
/**
* 带参构造函数
*
* @param name
* 昵称
* @param health
* 健康值
* @param love
* 亲密度
* @param strain
* 品种
*/
public Dog(String name, int health, int love, String strain) {
super(name, health, love);
this.setStrain(strain);
}
/**
* 输出狗狗信息
*/
public void print() {
System.out.println("宠物 的自白:\n我的名字叫" + super.getName() + ",健康值是"
+ super.getHealth() + ",和主人的亲密度是" + super.getLove() + ",我是一只"
+ this.strain + "。");
}
}
package cn.jbit.epetshop;
/**
* 宠物企鹅类
*
* @author Administrator
*
*/
public class Penguin extends Pet {
public final static String SEX_MALE = "Q仔"; // 性别
public final static String SEX_FEMALE = "Q妹"; // 性别
private String sex = SEX_FEMALE; // 性别
/**
* 读取性别
*
* @return 性别
*/
public String getSex() {
return sex;
}
/**
* 指定性别
*
* @param love
* 性别
*/
public void setSex(String sex) {
this.sex = sex;
}
/**
* 无参构造方法
*/
public Penguin() {
}
/**
* 带参构造方法
*
* @param name
* 昵称
* @param health
* 健康值
* @param love
* 亲密度
* @param sex
* 性别
*/
public Penguin(String name, int health, int love, String sex) {
super(name, health, love);
this.setSex(sex);
}
/**
* 输出企鹅信息
*/
public void print() {
System.out.println("宠物 的自白:\n我的名字叫" + super.getName() + ",健康值是"
+ super.getHealth() + ",和主人的亲密度是" + super.getLove() + ",性别是"
+ this.sex + "。");
}
}
public SubClass extends SuperClass{
//类定义部分
}
在Java中,继承(Inheritance)通过extends关键字来实现,其中SubClass称为子类,SuperClass称为父类,基类或超类。修饰符如果是public,该类在整个项目中可见;不写public修饰符则该类只在当前包可见;不可以使用private和protected修饰类。
继承是类的三大特性之一,是Java中实现代码重用的重要手段之一。Java中只支持单继承,即每个类只能有一个直接父类。继承表达的是is a的关系,或者说是一种特殊和一般的关系,例如Dog is a Pet。两样我们可以让学生继承人,让苹果继承水果,让三角形继承几何图形。
在Java中,子类可以从父类中继承到哪些“财产”呢?
- 继承public和protected修饰的属性和方法,不管子类和父类是否在同一个包里。
- 继承默认权限修饰符修饰的属性和方法,但子类和父类必须在同一个包里。
- 无法继承private修饰的属性和方法。
- 无法继承父类的构造方法。
super代表对当前对象的直接父类对象的默认引用。在子类中可以通过super关键字来访问父类的成员。
- super必须是出现在子类中(子类的方法和构造方法中),而不是其他位置。
- 可以访问父类的成员,例如父类的属性、方法、构造方法。
- 注意访问权限的限制,例如无法通过super访问private成员。
例如,在Dog类中可以通过如下语句来访问父类成员。
super.name;//访问直接父类的name属性(如果name是private权限,则无法访问)
super.print();//访问直接父类的print()方法
super(name);//访问直接父类的对应构造方法,只能出现在构造方法中。
继承条件下构造方法的调用规则如下。
- 如果子类的构造方法中没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法。在这种情况下,写不写“super();”语句,效果都是一样的。
- 如果子类的构造方法中通过super显式调用父类的有参构造方法,那将执行父类相应构造方法,而不执行父类无参构造方法。
- 如果子类的构造方法中通过this显式调用自身的其他构造方法,在相应构造方法中应用以上两条规则。
- 特别注意的是,如果存在多级继承关系,在创建一个子类对象时,以上规则会多次向更高一级父类应用,一直到执行顶级父类Object类的无参构造方法为止。
继承是Java中实现代码重用的重要手段之一。Java中只支持单继承,即一个类只能有一个直接父类。java.lang.Object类是所有Java类的祖先。
在子类中可以根据实际需求对从父类继承的方法进行重新编写,称为方法的重写或覆盖。
子类中重写的方法和父类中被重写方法必须具有相同的方法名,参数列表、返回值类型必须和被重写方法的返回值类型相同或者是子类。
在子类的构造方法中没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身的其他构造方法,则系统会默认先调用父类的无参构造方法。
抽象类不能实例化。抽象类中可以没有、可以有一个或多个抽象方法。子类必须重写所有的抽象方法才能实例化,否则子类还是一个抽象类。
用final修饰的类,不能再被继承。用final修饰的方法,不能被子类重写。用final修饰的变量将变成常量,只能赋值一次。
个人E-mail:chaoyi77@163.com