第1關:封裝、繼承和多態進階(一)
package case1;
import java.util.Scanner;
public class Task1 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String dogName = sc.next(); //輸入各屬性
String dogSex = sc.next();
String dogColor = sc.next();
String catName = sc.next();
String catSex = sc.next();
double catWeight = sc.nextDouble();
// 通過有參構造函數實例化Dog類對象dog
// dog調用talk()方法
// dog調用eat()方法
/********* begin *********/
Dog dog = new Dog(dogName,dogSex,dogColor);
dog.talk();
dog.eat();
/********* end *********/
// 通過有參構造函數實例化Cat類對象cat
// cat調用talk()方法
// cat調用eat()方法
/********* begin *********/
Cat cat=new Cat(catName,catSex,catWeight);
cat.talk();
cat.eat();
/********* end *********/
}
}
// 抽象類Pet 封裝屬性name和sex
// 構造函數初始化name和sex
// 聲明抽象方法talk()
// 聲明抽象方法eat()
abstract class Pet {
/********* begin *********/
private String name; //封裝屬性用private
private String sex;
public Pet(String name,String sex){
this.name=name;
this.sex=sex;
}
abstract void talk();
abstract void eat();
public String getName(){ //用get方法獲取屬性
return name;
}
public String getSex(){
return sex;
}
/********* end *********/
}
// Dog類繼承自Pet類 封裝屬性color
// 構造函數初始化name、sex和color
// 實現自己的talk()方法和eat()方法
// talk()輸出'名稱:name,性別:sex,顏色:color,汪汪叫'
// eat()輸出'name吃骨頭'
class Dog extends Pet {
/********* begin *********/
private String color;
public Dog(String name,String sex,String color){
super(name,sex); //用super初始化屬性
this.color=color;
}
public void talk(){
System.out.println("名稱:"+super.getName()+",性別:"+super.getSex()+",顏色:"+color+",汪汪叫");
} //super.方法名獲取屬性
public void eat(){
System.out.println(super.getName()+"吃骨頭!");
}
/********* end *********/
}
// Cat類繼承自Pet類 封裝屬性weight
// 構造函數初始化name、sex和weight
// 實現自己的talk()方法和eat()方法
// talk()輸出'名稱:name,性別:sex,體重:weight kg,喵喵叫'
// eat()輸出'name吃魚'
class Cat extends Pet {
/********* begin *********/
private double weight;
public Cat(String name,String sex,double weight){
super(name,sex);
this.weight=weight;
}
public void talk(){
System.out.println("名稱:"+super.getName()+",性別:"+super.getSex()+",體重:"+weight+"kg,喵喵叫");
}
public void eat(){
System.out.println(super.getName()+"吃魚!");
}
/********* end *********/
}
第2關:封裝、繼承和多態進階(二)
相關知識
為了完成本關任務,你需要掌握:1.重寫和重載;2.abstract
(抽象類)和interface
(接口);3.final
關鍵字;4.static
關鍵字;5.多態。
重寫和重載
方法重載(overload
):
- 必須是同一個類;
- 方法名(也可以叫函數)一樣;
- 參數類型不一樣或參數數量或順序不一樣;
- 不能通過返回值來判斷重載。
方法的重寫(override
)子類重寫了父類的同名方法,兩同兩小一大原則:
- 方法名相同,參數類型相同;
- 子類返回類型是父類返回類型的子類;
- 子類拋出異常小於等於父類方法拋出異常;
- 子類訪問權限大於等於父類方法訪問權限。
-
在重寫中,運用的是動態單分配,根據
new
的類型確定對象,從而確定調用的方法; -
在重載中,運用的是靜態多分配,根據靜態類型確定對象,不能根據
new
的類型確定調用方法; -
多態中,
Father f = new Son()
。成員變量:編譯運行參考左邊; 成員函數:編譯看左邊,運行看右邊; 靜態函數:編譯運行看左邊。
abstract
(抽象類)和interface
(接口)
抽象類
- 用
abstract
修飾的類表示抽象類,抽象類位於繼承樹的抽象層,抽象類不能被實例化。 - 用
abstract
修飾的方法表示抽象方法,抽象方法沒有方法體。抽象方法用來描述系統具有什么功能,但不提供具體的實現,把具體實現留給繼承該類的子類。
抽象類特點:
- 含有抽象方法的類必須聲明為抽象類(不管其中是否有其他方法);
- 抽象類可以沒有抽象方法,可以有普通方法;
- 抽象類必須被繼承,抽象方法必須被重寫(若子類還是抽象類,不需要重寫);
- 抽象類不能被實例化(不能直接構造一個該類的對象)。
抽象方法特點:
- 在類中沒有方法體(抽象方法只需聲明,而不需實現某些功能);
- 抽象類中的抽象方法必須被實現;
- 如果一個子類沒有實現父類中的抽象方法,則子類也變成了一個抽象類。
接口 interface
中的方法默認為public
abstract
(public
、abstract
可以省略),變量默認為public static final
;類中的方法全部都是抽象方法。只有聲明沒有實現,在不同類中有不同的方法實現。
不同點:
- 接口中只能包含抽象方法和默認方法,不能為普通方法提供方法實現;抽象類中可以包含普通方法;
- 接口里不能定義靜態方法(
jdk1.8
下可以定義static
方法),抽象類可以定義靜態方法; - 接口中只能定義靜態常量,不能定義普通成員變量;抽象類即可以定義變量又可以定義靜態常量;
- 接口中不包含構造器,抽象類里可以包含構造器,抽象類中的構造器並不是用於創建對象,而是讓其他子類調用這些構造器來完成抽象類的初始化操作;
- 接口里不能包含初始化塊,但抽象類可以包含;
- 一個類最多只能有一個父類,包括抽象類;但一個類可以直接實現多個接口,通過實現多個接口可以彌補Java單繼承的不足。
共同點:
- 接口和抽象類都不能被實例化,都位於繼承樹的頂端,用於被其他類實現的繼承;
- 接口和抽象類都可以包含抽象方法,實現接口和繼承抽象類的普通子類都必須實現這些方法。
final
關鍵字
final
修飾的類,就是最終類,不能被繼承。final
修飾的方法,就是最終方法,最終方法不能被重寫。final
修飾一個引用變量時,是指引用變量不能變,引用變量所指向的對象中的內容還是可以改變的。修飾基本數據類型變量時,內容不能變。final
成員變量必須在初始化代碼塊或在構造器中初始化。
作用:
final
類:如果一個類不需要有子類,類的實現細節不允許改變,並且確信這個類不會再被擴展,那么就設計成final
類。final
方法:①把方法鎖定,防止任何繼承類修改它的意義和實現。②高效,編譯器在遇到調用final
方法時候會轉入內嵌機制,大大提升執行效率。
static
關鍵字
static
修飾的變量稱為靜態變量,靜態變量屬於整個類,而局部變量屬於方法,只在該方法內有效。static
不能修飾局部變量。static
方法內部不能調用非靜態方法。- 靜態變量只能在類主體中定義,不能在方法中定義;
static
變量只會創建一份,不管創建幾個對象,都共用一個變量。
類方法指被static
修飾的方法,無this
指針。其他的就是實例方法。類方法可以調用其他類的static
方法。 類方法和對象方法的區別:
1、 類方法是屬於整個類的,而實例方法是屬於類的某個對象的。 由於類方法是屬於整個類的,並不屬於類的哪個對象,所以類方法的方法體中不能有與類的對象有關的內容。即類方法體有如下限制:
- 類方法中不能引用對象變量;
- 類方法中不能調用類的對象方法;
- 在類方法中不能使用
super
、this
關鍵字。(this
表示當前類的對象,由static
修飾的方法是類直接調用,不需要創建對象,所以不能用this
); - 類方法不能被覆蓋。
2、與類方法相比,對象方法幾乎沒有什么限制:
- 對象方法中可以引用對象變量,也可以引用類變量;
- 對象方法中可以調用類方法;
- 對象方法中可以使用
super
、this
關鍵字。
static
關鍵字的作用
- 為某特定數據類型或對象分配單一的存儲空間,而與創建對象的個數無關;實現某個方法或屬性與類而不是對象關聯在一起;
- 靜態變量屬於類,在內存中只有一個復制,只要靜態變量所在的類被加載,這個靜態變量就會被分配空間。
多態
-
定義:不同類的對象對同一消息做出響應。同一消息可以根據發送對象的不同而采用多種不同的行為方式;
-
多態存在的三個必要條件:繼承、重寫、父類引用指向子類對象;
-
Java中多態的實現方式:接口實現,繼承父類進行方法重寫,同一個類中進行方法重載;
-
父類引用指向子類對象,該引用不能再訪問子類新增的成員。
Animal cat = new Cat()
與直接new
一個父類實例(Animal a = new Animal()
)的區別? 答:當父類是接口和抽象類時,不能實例化,只能運用多態,向上轉型。普通類中,可以在子類中重寫父類中的方法,這樣就可以訪問子類中的重寫方法。
package case2;
import java.util.Scanner;
public class Task2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String cName = sc.next();
String cSex = sc.next();
int cAge = sc.nextInt();
String eName = sc.next();
String eSex = sc.next();
int eAge = sc.nextInt();
// 創建測試類對象test
// 創建Person類對象person1,引用指向中國人,通過有參構造函數實例化中國人類對象
// 通過showEat()方法調用Chinese的eat()方法
// 創建Person類對象person2,引用指向英國人,通過有參構造函數實例化英國人類對象
// 通過showEat()方法調用English的eat()方法
/********* begin *********/
Person person1 = new Chinese(cName,cSex,cAge); //抽象類Person不能被實例化
showEat(person1); //showEat是靜態方法可以調用
Person person2=new English(eName,eSex,eAge);
showEat(person2);
/********* end *********/
// 強制類型轉換(向下轉型) 調用Chinese類特有的方法shadowBoxing()
// 強制類型轉換(向下轉型) 調用English類特有的方法horseRiding()
/********* begin *********/
Chinese d = (Chinese) person1;
d.shadowBoxing(); //使用特有的方法就需要向下轉型,因為person1屬於Person類
English f =(English) person2;
f.horseRiding();
/********* end *********/
}
// 定義showEat方法,使用父類作為方法的形參,實現多態,傳入的是哪個具體對象就調用哪個對象的eat()方法
/********* begin *********/
public static void showEat(Person p){
p.eat();
}
/********* end *********/
}
// 抽象類Person 封裝屬性name、sex和age
// 構造函數初始化name、sex和age
// 聲明抽象方法eat()
abstract class Person {
/********* begin *********/
String name;String sex;int age;
Person(String name,String sex,int age){
this.name=name;this.sex=sex;this.age=age;
}
abstract void eat();
/********* end *********/
}
// Chinese類繼承自Person類
// 構造函數初始化name、sex和age
// 重寫父類方法eat() 輸出'姓名:name,性別:sex,年齡:age,我是中國人,我喜歡吃飯!'
// 定義子類特有方法shadowBoxing(),當父類引用指向子類對象時無法調用該方法 輸出'name在練習太極拳!'
class Chinese extends Person {
/********* begin *********/
public Chinese(String name,String sex,int age){
super(name,sex,age);
}
/********* end *********/
@Override
void eat(){
System.out.println("姓名:"+name+",性別:"+sex+",年齡:"+age+",我是中國人,我喜歡吃飯!");
}
void shadowBoxing(){
System.out.println(name+"在練習太極拳!");
}
}
// English類繼承自Person類
// 構造函數初始化name、sex和age
// 重寫父類方法eat() 輸出'姓名:name,性別:sex,年齡:age,我是英國人,我喜歡吃三明治!'
// 定義子類特有方法horseRiding(),當父類引用指向子類對象時無法調用該方法 輸出'name在練習騎馬!'
class English extends Person {
/********* begin *********/
public English(String name,String sex,int age){
super(name,sex,age);
}
@Override
void eat(){
System.out.println("姓名:"+name+",性別:"+sex+",年齡:"+age+",我是英國人,我喜歡吃三明治!");
}
void horseRiding(){
System.out.println(name+"在練習騎馬!");
}
/********* end *********/
}
/*知識點目錄
1,Java繼承
1.1 繼承的概念
1.2 繼承的特性
1.3 繼承關鍵字
1.4 構造器
2,Java重寫(Override)與重載(Overload)
2.1 重寫(Override)
2.2 重載(Overload)
2.3 總結
3,Java多態
3.1 多態的實現方式
4,Java抽象類
5,Java封裝
6,Java接口
*/
/* 1.1繼承的概念
繼承在本職上是特殊——一般的關系,即常說的is-a關系。子類繼承父類,表明子類是一種特殊的父類,並且具有父類所不具有的一些屬性或方法。通過 extends 關鍵字可以聲明一個類是從另外一個類繼承而來的。
*/
/* 1.2繼承的特性
1).子類擁有父類非private的屬性,方法;
2).子類可以擁有自己的屬性和方法,即子類可以對父類進行擴展;
3).子類可以用自己的方式實現父類的方法;
4).Java的繼承是單繼承,這是Java繼承區別於C++繼承的一個特性;
5).提高了類之間的耦合性(繼承的缺點,耦合度高就會造成代碼之間的聯系)。
*/
/* 1.3繼承關鍵字
1).使用 extends 和 implements 來實現繼承,所有的類都是繼承於 java.lang.Object,當一個類沒有繼承的兩個關鍵字,則默認繼承Object;
2).一個子類只能擁有一個父類,所以 extends 只能繼承一個類;
3).使用 implements 關鍵字變相的使Java具有多繼承的特性,為類繼承接口,可以同時繼承多個接口;
4).通過super關鍵字來實現對父類成員的訪問,用來引用當前對象的父類;
5).final 關鍵字
5.1) 聲明類則把類定義為不能繼承的,即最終類;修飾方法,則該方法不能被子類重寫;定義實例變量,則變量不能被修改;
5.2) final 類的方法自動為 final方法,但實例變量不自動是 final變量。
*/
interface A{}
interface B{}
class Animal{
public void move(){
System.out.println("動物可以移動");
}
Animal(){
System.out.println("Animal()");
}
Animal(int n){
System.out.println("Animal(int)");
}
}
final class Dog extends Animal implements A,B {
final String name = "旺財";
final public void finalFun(){
}
/* 2.1.1 重寫(Override)
1).重寫是子類對父類的允許訪問的方法的實現過程進行重新編寫, 返回值和形參都不能改變。即外殼不變,核心重寫;
2).重寫的好處在於子類可以根據需要,定義特定於自己的行為。也就是說子類能夠根據需要實現父類的方法;
3).重寫方法不能拋出新的檢查異常或者比被重寫方法聲明更加寬泛的異常。
*/
public void move(){
System.out.println("狗可以跳牆");
}
/*2.2.1重載(Overload)
1).重載是在一個類里面,方法名字相同,而參數不同。返回類型可以相同也可以不同;
2).每個重載的方法(或者構造函數)都必須有一個獨一無二的參數類型列表。
*/
public void move(int n){
System.out.println("這只狗可以跳"+n+"米的牆");
}
public String toString() {
//1.3.1 通過super關鍵字來實現對父類成員的訪問,用來引用當前對象的父類。
return "I am a Dog " + super.toString();
}
/* 1.4 構造器
1).子類不能繼承父類的構造器(構造方法或者構造函數),但是父類的構造器帶有參數的,則必須在子類的構造器中顯式地通過super關鍵字調用父類的構造器並配以適當的參數列表;
2).如果父類有無參構造器,則在子類的構造器中用super調用父類構造器不是必須的,如果沒有使用super關鍵字,系統會自動調用父類的無參構造器。
*/
Dog(){
super(300);
System.out.println("Dog()");
}
Dog(int n){
System.out.println("Dog(int)");
}
}
class Test{
static void testsuper(){
System.out.println("-----testsuper----");
new Dog();
new Dog(1);
}
static void testoverride(){
System.out.println("-----testoverride-----");
Animal a = new Animal();
Animal b = new Dog();
a.move();
/*2.1.2 重寫(Override)
1).盡管b屬於Animal類型,但是它運行的是Dog類的move方法;
2).在編譯階段,只是檢查參數的引用類型。在運行時,Java虛擬機(JVM)指定對象的類型並且運行該對象的方法。
*/
b.move();
}
}
public class JavaDemo{
public static void main(String[] args) {
Test.testsuper();
Test.testoverride();
}
}
/* 2.1.3方法的重寫規則
1).參數列表必須完全與被重寫方法的相同;
2).返回類型必須完全與被重寫方法的返回類型相同;
3).訪問權限不能比父類中被重寫的方法的訪問權限更低;
4).父類的成員方法只能被它的子類重寫;
5).聲明為final的方法不能被重寫;
6).聲明為static的方法不能被重寫,但是能夠被再次聲明;
7).子類和父類在同一個包中,那么子類可以重寫父類所有方法,除了聲明為private和final的方法;
8).子類和父類不在同一個包中,那么子類只能夠重寫父類的聲明為public和protected的非final方法;
9).重寫的方法能夠拋出任何非強制異常,無論被重寫的方法是否拋出異常,但是,重寫的方法不能拋出新的強制性異常,或者比被重寫方法聲明的更廣泛的強制性異常,反之則可以;
10).構造方法不能被重寫;
11).如果不能繼承一個方法,則不能重寫這個方法。
*/
/*2.2.2重載規則
1).被重載的方法必須改變參數列表(參數個數或類型或順序不一樣);
2).被重載的方法可以改變返回類型;
3).被重載的方法可以改變訪問修飾符;
4).被重載的方法可以聲明新的或更廣的檢查異常;
5).方法能夠在同一個類中或者在一個子類中被重載;
6).無法以返回值類型作為重載函數的區分標准。
*/
/*
重寫與重載之間的區別
區別點 重載方法 重寫方法
參數列表 必須修改 一定不能修改
返回類型 可以修改 一定不能修改
異常 可以修改 可以減少或刪除,一定不能拋出新的或者更廣的異常
訪問 可以修改 一定不能做更嚴格的限制(可以降低限制)
總結
方法的重寫和重載是Java多態性的不同表現,重寫是父類與子類之間多態性的一種表現,重載是一類中多態性的一種表現。
*/
/*訪問控制修飾符
Java中,可以使用訪問控制符來保護對類、變量、方法和構造方法的訪問。Java支持4種不同的訪問權限。
默認的,也稱為 default,在同一包內可見,不使用任何修飾符;
私有的,以 private 修飾符指定,在同一類內可見;
共有的,以 public 修飾符指定,對所有類可見;
受保護的,以 protected 修飾符指定,對同一包內的類和所有子類可見。
我們可以可以通過以下表來說明訪問權限:
訪問控制
修飾符 當前類 同一包內 子孫類 其他包
public Y Y Y Y
protected Y Y Y N
default Y Y N N
private Y N N N
*/
/*3,Java多態
多態就是同一個接口,使用不同的實例執行不同操作。
3.1 多態的實現方式 重寫、接口、抽象類和抽象方法。
*/
/*4,Java抽象類
1).使用abstract class來定義抽象類,抽象類不能被實例化;
2).抽象類中不一定包含抽象方法,但是有抽象方法的類必定是抽象類;
3).抽象類中的抽象方法只是聲明,不包含方法體;
4).構造方法,類方法(用static修飾的方法)不能聲明為抽象方法;
5).任何子類必須重寫父類的抽象方法,或者聲明自身為抽象類。
*/
abstract class Employee{
//抽象方法
public abstract double computePay();
}
/*4.2繼承抽象類
*/
class Salary extends Employee{
public double computePay(){
return 0;
}
}
/*
5,Java封裝
封裝(英語:Encapsulation)是指,一種將抽象性函式接口的實現細節部份包裝、隱藏起來的方法。
封裝的優點:
1).良好的封裝能夠減少耦合;
2).類內部的結構可以自由修改;
3). 可以對成員變量進行更精確的控制;
4). 隱藏信息,實現細節。
實現Java封裝的步驟:
1). 修改屬性的可見性來限制對屬性的訪問;
2).對每個值屬性提供對外的公共方法訪問。
*/
/*
6,Java接口
1).接口,在Java編程語言中是一個抽象類型,是抽象方法的集合,接口通常以interface來聲明;
2).一個實現接口的類,必須實現接口內所描述的所有方法,否則就必須聲明為抽象類;
3).接口不能包含成員變量,除了 static 和 final 變量;
4).接口中每一個方法也是隱式抽象的,接口中的方法會被隱式的指定為 public abstract;
5).接口中可以含有變量,但是接口中的變量會被隱式的指定為 public static final 變量;
6).接口中的方法是不能在接口中實現的,只能由實現接口的類來實現接口中的方法;
7).類在實現接口的方法時,不能拋出強制性異常,只能在接口中,或者繼承接口的抽象類中拋出該強制性異常;
8).類在重寫方法時要保持一致的方法名,並且應該保持相同或者相兼容的返回值類型;
9).接口的繼承使用extends關鍵字,允許多重繼承,可能定義或繼承相同的方法。
*/
interface C extends A,B{}
package case3;
import java.util.Scanner;
public class Task3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String pppName = sc.next();
int pppAge = sc.nextInt();
String bpName = sc.next();
int bpAge = sc.nextInt();
String ppcName = sc.next();
int ppcAge = sc.nextInt();
String bcName = sc.next();
int bcAge = sc.nextInt();
// 測試運動員(乒乓球運動員和籃球運動員)
// 乒乓球運動員
// 通過帶參構造函數實例化PingPangPlayer對象ppp
// 輸出'name---age'
// 分別調用sleep()、eat()、study()、speak()方法
/********* begin *********/
PingPangPlayer ppp = new PingPangPlayer(pppName, pppAge);
System.out.println(pppName+"---"+pppAge);
ppp.sleep();ppp.eat();ppp.study();ppp.speak();
/********* end *********/
System.out.println("----------------");
// 籃球運動員
// 通過帶參構造函數實例化BasketballPlayer對象bp
// 輸出'name---age'
// 分別調用sleep()、eat()、study()方法
/********* begin *********/
BasketballPlayer bp = new BasketballPlayer(bpName, bpAge);
System.out.println(bpName+"---"+bpAge);
bp.sleep();bp.eat();bp.study();
/********* end *********/
System.out.println("----------------");
// 測試教練(乒乓球教練和籃球教練)
// 乒乓球教練
// 通過帶參構造函數實例化PingPangCoach對象ppc
// 輸出'name---age'
// 分別調用sleep()、eat()、teach()、speak()方法
/********* begin *********/
PingPangCoach ppc = new PingPangCoach(ppcName,ppcAge);
System.out.println(ppcName+"---"+ppcAge);
ppc.sleep();ppc.eat();ppc.teach();ppc.speak();
/********* end *********/
System.out.println("----------------");
// 籃球教練
// 通過帶參構造函數實例化BasketballCoach對象bc
// 輸出'name---age'
// 分別調用sleep()、eat()、teach()方法
/********* begin *********/
BasketballCoach bc = new BasketballCoach(bcName,bcAge);
System.out.println(bcName+"---"+bcAge);
bc.sleep();bc.eat();bc.teach();
/********* end *********/
System.out.println("----------------");
}
}
// 說英語接口 聲明抽象方法speak()
interface SpeakEnglish {
/********* begin *********/
abstract void speak();
/********* end *********/
}
// 定義人的抽象類Person 封裝name和age
// 無參構造函數
// 有參構造函數初始化name和age
// 定義具體方法sleep() 輸出'人都是要睡覺的'
// 抽象方法eat()(吃的不一樣)
abstract class Person {
/********* begin *********/
private String name;
private int age;
public Person(){}
public Person(String name,int age){
this.name=name;
this.age=age;
}
public void sleep(){
System.out.println("人都是要睡覺的");
}
public String getName(){return name;}
public int getAge(){return age;}
/********* end *********/
}
// 定義運動員Player(抽象類)繼承自Person類
// 無參構造函數
// 有參構造函數初始化name和age
// 運動員學習內容不一樣,抽取為抽象 定義抽象方法study()
abstract class Player extends Person {
private String name;
private int age;
/********* begin *********/
public Player(){}
public Player(String name,int age){
super(name,age);
}
abstract void study();
public String getName(){return name;}
public int getAge(){return age;}
/********* end *********/
}
// 定義教練Coach(抽象類)繼承自Person類
// 無參構造函數
// 有參構造函數初始化name和age
// 教練教的不一樣 定義抽象方法teach()
abstract class Coach extends Person {
/********* begin *********/
private String name;
private int age;
/********* begin *********/
public Coach(){}
public Coach(String name,int age){
super(name,age);
}
abstract void teach();
public String getName(){return name;}
public int getAge(){return age;}
/********* end *********/
}
// 定義乒乓球運動員具體類PingPangPlayer 繼承自Player類並實現SpeakEnglish類(兵乓球運動員需要說英語)
// 無參構造函數
// 有參構造函數初始化name和age
// 實現自己的eat()方法 輸出'乒乓球運動員吃大白菜,喝小米粥'
// 實現自己的study()方法 輸出'乒乓球運動員學習如何發球和接球'
// 實現自己的speak()方法 輸出'乒乓球運動員說英語'
class PingPangPlayer extends Player implements SpeakEnglish {
/********* begin *********/
String name;int age;
public PingPangPlayer(){}
public PingPangPlayer(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("乒乓球運動員吃大白菜,喝小米粥");
}
public void study(){
System.out.println("乒乓球運動員學習如何發球和接球");
}
public void speak(){
System.out.println("乒乓球運員說英語");
}
/********* end *********/
}
// 定義籃球運動員具體類BasketballPlayer 繼承自Player類 不需要繼承接口,因為他不需要說英語
// 無參構造函數
// 有參構造函數初始化name和age
// 實現自己的eat()方法 輸出'籃球運動員吃牛肉,喝牛奶'
// 實現自己的study()方法 輸出'籃球運動員學習如何運球和投籃'
class BasketballPlayer extends Player {
/********* begin *********/
String name;int age;
public BasketballPlayer(){}
public BasketballPlayer(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("籃球運動員吃牛肉,喝牛奶");
}
public void study(){
System.out.println("籃球運動員學習如何運球和投籃");
}
/********* end *********/
}
// 定義乒乓球教練具體類 PingPangCoach 繼承自Coach類並實現SpeakEnglish類(兵乓球教練需要說英語)
// 無參構造函數
// 有參構造函數初始化name和age
// 實現自己的eat()方法 輸出'乒乓球教練吃小白菜,喝大米粥'
// 實現自己的teach()方法 輸出'乒乓球教練教如何發球和接球'
// 實現自己的speak()方法 輸出'乒乓球教練說英語'
class PingPangCoach extends Coach implements SpeakEnglish {
/********* begin *********/
String name;int age;
public PingPangCoach(){}
public PingPangCoach(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("乒乓球教練吃小白菜,喝大米粥");
}
public void teach(){
System.out.println("乒乓球教練教如何發球和接球");
}
public void speak(){
System.out.println("乒乓球教練說英語");
}
/********* end *********/
}
// 定義籃球教練具體類BasketballCoach 繼承自Coach類 不需要繼承接口,因為他不需要說英語
// 無參構造函數
// 有參構造函數初始化name和age
// 實現自己的eat()方法 輸出'籃球教練吃羊肉,喝羊奶'
// 實現自己的teach()方法 輸出'籃球教練教如何運球和投籃'
class BasketballCoach extends Coach {
/********* begin *********/
String name;int age;
public BasketballCoach(){}
public BasketballCoach(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("籃球教練吃羊肉,喝羊奶");
}
public void teach(){
System.out.println("籃球教練教如何運球和投籃");
}
/********* end *********/
}