Educoder-Java程式開發基礎-繼承與多型(二)
第1關:繼承-1
本關任務:定義一個表示“僱員”(Employee)的類。定義一個表示“經理”(Manager)的類繼承Employee,經理每月獲得一份固定的工資。定義一個表示“工人”(Worker)的類繼承Employee,工人按每月工作的天數計算工資。
package test_extend; /** * @author pengzheng */ class Employee { // 定義員工類 String name; int age; double salary; // 定義 double型別的成員變數salary,表示工資 Employee(String name, int age) { this.name = name; this.age = age; // 初始化成員變數age } void showInfo() { System.out.println("姓名是:" + this.name); System.out.println("年齡是:" + this.age); System.out.println("工資是:" + this.salary);// 顯示工資的資訊,格式為“工資是:***” } } class Manager extends Employee { // 定義Manager類,繼承Employee類 Manager(String name, int age, double salary) { super(name, age); // 呼叫父類構造方法,以初始化成員變數name和age this.salary = salary; } } class Worker extends Employee { // 定義“工人”類Worker,繼承“員工”類Employee int workingDays; // 成員變數workingDays,表示工作天數 double dailyWage; // 定義 double型別的成員變數 dailyWage,表示日薪 void setSalary(int workingDays, double dailyWage) { this.workingDays = workingDays; this.dailyWage = dailyWage; this.salary = workingDays * dailyWage; // 工資=工作天數*日薪 } Worker(String name, int age, int workingDays, double dailyWage) { super(name,age); // 呼叫父類構造方法,以初始化name和age setSalary(workingDays,dailyWage); // 呼叫成員方法setSalary,以初始化工作天數、日薪和月薪 } void showInfo() { // 覆蓋override父類的showInfo()方法 super.showInfo(); // 呼叫父類被覆蓋的showInfo(),以顯示姓名、年齡、工資的資訊 System.out.println("工作天數是:" + this.workingDays); System.out.println("日薪是:" + this.dailyWage); } } public class TestExtend { public static void main(String[] args) { Manager manager = new Manager("張三",40,10000); // 建立一個經理物件:張三、40歲、10000元月薪 manager.showInfo(); // 呼叫manager的showInfo()方法,顯示該經理的資訊。 Worker worker = new Worker("李四",20,22,200); // 建立Worker物件:李四、20歲、月工作22天、日薪200 worker.showInfo(); } }
第2關:繼承-2
本關任務:定義一個表示“汽車”的類Vehicle。定義了屬性:車輪數wheels和車重weight;構造方法用以初始化物件屬性;show方法用以輸出相關屬性。定義Vehicle類的子類Trunk,表示“卡車”,新增屬性load,表示載重量;定義Vehicle類的子類Minibus,表示“麵包車”,新增屬性passenger,表示載客數。為這兩個類定義合適的構造方法用以初始化物件屬性,需要顯示呼叫父類構造方法。為這兩個類定義show方法用以輸出相關屬性,需要覆蓋Override父類的show方法。
package test_vehicle; /** * @author pengzheng */ class Vehicle { int wheels; // 車輪數 float weight; // 車重 Vehicle(int wheels, float weight) { this.wheels = wheels; this.weight = weight; } void show() { System.out.print("車輪:" + this.wheels); System.out.print(", 車重:" + this.weight); } } //定義Vehicle類的子類Trunk,表示“卡車”,新增float型別的屬性load,表示載重量 /********* begin *********/ class Trunk extends Vehicle{ float load; public Trunk(int wheels, float weight,float load){ super(wheels,weight); this.load=load; } /********* begin *********/ /********* end *********/ void show() { System.out.println("車型:卡車"); super.show(); System.out.println(", 載重量:" + this.load); } } // 定義Vehicle類的子類Minibus,表示“麵包車”,新增int型別的屬性passenger,表示載客數。 // 定義合適的構造方法用以初始化物件屬性,需要顯示呼叫父類構造方法。 /********* begin *********/ class Minibus extends Vehicle{ int passenger; public Minibus(int wheels, float weight,int passenger){ super(wheels,weight); this.passenger=passenger; } /********* end *********/ // 覆蓋Override父類的show方法。 void show() { System.out.println("車型:麵包車"); /********* begin *********/ super.show(); /********* end *********/ System.out.println(", 載人:" + this.passenger); } } public class TestVehicle { public static void main(String[] args) { Vehicle trunk = new Trunk(6, 7500, 80); trunk.show(); Vehicle minibus = new Minibus(4, 3000, 12); minibus.show(); } }
第3關:訪問控制
本關任務:請用註釋的方式指出程式碼中的語法錯誤,並修改使其能通過編譯、正確執行,請參考預期輸出
package access_control; class SupClass { //public final int CONST = 1; int i; protected int j; public SupClass(int i, int j) { // CONST = 2; this.i = i; this.j = j; } //final void m1() { // System.out.println("SupClass m1()"); //} void m2() { System.out.println("SuperClass m2()"); } } class SubClass extends SupClass { public int k; public SubClass(int i, int j, int k) { super(i,j); this.i = i; this.j = j; this.k = k; } void m1() { System.out.println("SubClass m1()"); System.out.println("SubClass m1()"); } void m2() { System.out.println("SubClass m2()"); } } public class FindWrong { public static void main(String[] args) { SubClass sub = new SubClass(1,2, 3); //System.out.println(sub.i); System.out.println(sub.j); System.out.println(sub.k); sub.m1(); sub.m2(); } }
第4關:抽象類
本關任務:定義了一個表示“形狀”(Shape)的抽象類,定義Shape類的子類:長方形類(Rectangle)、圓形類(Circle),在主類的main方法中建立了兩個形狀物件,並打印出這兩個形狀的面積
package test_abstract;
abstract class Shape { // 定義一個抽象類Shape,表示形狀
public double area; // 面積
abstract double getArea(); // 宣告一個抽象方法 getArea(),方法的返回值型別是double
}
class Rectangle extends Shape { // 定義一個表示矩形的類Rectangle,繼承Shape
public double length; // 長
public double width; // 寬
public Rectangle(double length, double width) { // 構造方法
this.length = length; // 初始化成員變數length
this.width = width;
}
public double getArea() { // 實現父類的抽象方法 getArea()
return length*width; // 返回矩形的面積
}
}
class Circle extends Shape { // 定義一個表示圓形的類Circle,繼承Shape
public double radius; // 半徑
public Circle(double radius){ // 定義Circle類的構造方法
this.radius=radius;
}
public double getArea() {
return radius * radius * Math.PI;
}
}
public class TestAbstract {
public static void main(String[] args) {
Shape s1 = new Rectangle(4,5); // 建立一個長為4,寬為5的矩形物件。
System.out.println(s1.getArea());
Shape s2 = new Circle(3);
System.out.println(s2.getArea()); // 打印出形狀s2的面積
}
}
第5關:介面
1、所有的門(Door)都具有開(open)和關(close)的功能,但是不同型別的門,它們開和關的方式可能是不一樣的,所以可以把“門”定義為一個抽象類Door。 2、有些門具有報警(alarm)的功能,但不是所有型別的門都具有報警的功能,所以可以把“能報警”的行為特徵定義為一個介面Alarmable。 3、“安全門”是一種具體型別的門,它除了具有一般“門”的特性之外,還具有“能報警”的功能,所以可以把“安全門”定義為一個繼承抽象類“門”並實現介面“能報警”的具體類SafetyDoor。
package test_interface;
/**
* @author pengzheng
*/
//定義一個抽象類Door,宣告抽象方法open和close
/********* begin *********/
abstract class Door{
abstract void open();
abstract void close();
}
/********* end *********/
//定義一個介面Alarmable,宣告方法alarm
/********* begin *********/
interface Alarmable{
public void alarm();
}
/********* end *********/
//定義一個類SafetyDoor,使其繼承Door,並實現介面Alarmable
/********* begin *********/
class SafetyDoor extends Door implements Alarmable{
/********* end *********/
@Override
public void alarm() {
System.out.println("alarm");
}
//實現open方法,方法體內打印出"open"
/********* begin *********/
public void open(){
System.out.println("open");
}
/********* end *********/
//實現close方法,方法體內打印出"close"
/********* begin *********/
public void close(){
System.out.println("close");
}
/********* end *********/
}
public class TestInterface {
public static void main(String[] args) {
SafetyDoor safetyDoor = new SafetyDoor();
safetyDoor.open();
safetyDoor.close();
safetyDoor.alarm();
}
}