實驗3 繼承與多態
**類可以實現多個接口 但只有單繼承!**
1、繼承
1)、繼承語法
class 子類名 extends 父類{
}
2)、構造函數(通過source即可得到)
注意: 當子類實例化,首先調用父類構造函數,其次調用子類本身構造函數
3)、函數重載:
簡單來說 相同函數名 參數需求不同 在調用時自動尋找匹配的函數
4)、覆蓋問題override
子類重寫了一個從父類繼承過來的函數與屬性
---當使用時就直接使用子類函數
直接alt加 / 鍵就可重寫
2、final(用此定義的屬性 為常量)
1)、final定義的方法可繼承,但不可override!
2)、fianl定義的類不可派生子類(不可繼承),但能生成對象
3)、final變量對於對象實例a,不可修改指針(×b=a),但可修改實例的內部值(a.heigtht可修改)
3、abstract(抽象)
1)abstract函數:函數只有聲明沒有函數體(沒有實現)
public abstract double area();
注意:此函數主要用作給子類override!
如果有抽象函數則必是抽象類
2)abstract類:不能實例化,只能作為父類被其他類繼承,可有成員函數、屬性、抽象函數
abstract class Shape{
public abstract double area();
/*可以其他非抽象函數*/
}
注意:此類主要用作子類對象的相同處、都有的屬性(金字塔頂)
子類必須實現所有父類抽象類的方法,除非子類也是抽象類
只有實現所有父親的抽象類 才能成為非抽象類
4、接口:interface 都是抽象方法和一些靜態屬性.
具體的方法在子類中實現
1)定義接口
interface Shape{
double pi=3.14;
double area();
}
2)類實現接口:如果不是抽象類,就需要實現接口中所有抽象方法
3)類實現多個接口 ,用,隔開
class Circle implements Shape,Color{}
抽象類與接口的區別:
1 抽象類有部分方法可實現
2 接口所有方法都不可實現
3 接口繼承多個接口,抽象類只能繼承一個抽象類
4 抽象類有構造函數 接口沒有
5 抽象類中可有main函數運行 接口不行
6 抽象類成員 private,public,protected
7 接口成員只能是public
實踐編程
1、實現一個名為Person的類和它的子類Employee
具體要求如下:
(1) Person類中的屬性有:姓名name(String類型),地址address(String類型),電話號碼telphone(String類型);
public class Person { private String name; private String address; private String telephone; public Person(String name, String address, String telephone) { super(); this.name = name; this.address = address; this.telephone = telephone; } @Override public String toString() { return "name=" + name + ", address=" + address + ", telephone=" + telephone ; } }
(2)Employee類中的屬性有:辦公室office(String類型),工資wage(double類型)
public class Employee extends Person { private String office; private double wage; public Employee(String name, String address, String telephone, String office, double wage) { super(name, address, telephone); this.office = office; this.wage = wage; } @Override public String toString() { return super.toString()+", office=" + office + ", wage=" + wage ; } }
(3)測試代碼,各個屬性賦值在構造函數中完成。
public class test { public static void main(String[] args) { Employee e=new Employee("cf", "China", "911", "school", 20000); System.out.println(e.toString()); } }
2.方法調用匹配測試
class methodMatch{ double x=5,y=6; void test( double y ){ System.out.println(y); test(this); //轉換匹配哪個方法 } public String toString(){ return x+","+y; } void test( String a){ System.out.println(a); } void test( Object a){ System.out.println(a); } public static void main(String args[]) { methodMatch a=new methodMatch (); a.test(8); a.test("hello"); } }
Q:分析以上程序運行結果,刪除test(String)方法后結果如何?加入一個test(int)方法執行結果又如何?最后,總結方法調用的匹配原則。
A:
8.0
5.0,6.0
hello
先找是否有與其變量匹配的
若沒有則進入obj(萬物皆對象)
Print(obj)時會調用tostring方法
3.將以下程序補充完整
public class Java_3{ public static void main(String[] args){ Person p = new Student("王甜甜", "計算機科學"); System.out.println(p.getName() + ", "+ p.getDescription()); } } abstract class Person{ public Person(String n){ name = n; } //*********Found******** public __abstract____ String getDescription(); public String getName(){ return name; } private String name; } //*********Found******** class Student ___extends__ Person{ public Student(String n, String m){ super(n); major = m; } //*********Found******** public String __getDescription___(){ return "學生專業是:" + major; } private String major; }
注意:
1 abstract函數:函數只有聲明沒有函數體(沒有實現)--》在子類中實現
2父類的所有抽象函數都需要實現
4 編寫一個抽象的圖形類Shape,里面有方法area()計算面積以及方法displayArea()顯示面積,編寫子類矩形類和三角型類分別實現兩個方法。
抽象shape類
public abstract class Shape { abstract double area(); abstract void displayArea(); }
注意: abstract函數:函數只有聲明沒有函數體(沒有實現)--》在子類中實現
子類矩形類
public class MyRectangle extends Shape { private double length; private double width; public MyRectangle(double length, double width) { super(); this.length = length; this.width = width; } @Override double area() { return length*width; } /* * 覆蓋了父類Shape的displayArea函數 */ @Override void displayArea() { System.out.println("Rectangle's area:"+area()); } }
注意:父類的所有抽象函數都需要實現
子類三角型類
public class MyTriangle extends Shape { private double length; private double height; public MyTriangle(double length, double height) { super(); this.length = length; this.height = height; } @Override double area() { return 0.5*length*height; } /* * 覆蓋了父類Shape的displayArea函數 */ @Override void displayArea() { System.out.println("Triangle's area:"+area()); } }
測試數據
public class test { public static void main(String[] args) { Shape a=new MyRectangle(10, 20.5); Shape b=new MyTriangle(10, 20.5); a.displayArea(); b.displayArea(); } }
5、編寫一個完整的Java Application 程序。包含接口Shape,MyRectangle類,MyTriangle類及Test類,具體要求如下:
⑴、接口ShapeArea:
double area():求一個形狀的面積
double perimeter ():求一個形狀的周長
interface ShapeArea { double area(); double perimeter(); }
⑵、類 MyRectangle:
實現Shape接口,並有以下屬性和方法:
① 屬性
width: double類型,表示矩形的長
height: double類型,表示矩形的高
② 方法
MyRectangle(double w, double h):構造函數
toString()方法 :輸出矩形的描述信息,如“width=1.0,height=2.0, perimeter=6.0, area=2.0”
class MyRectangle implements ShapeArea { private double width; private double height; public MyRectangle(double width, double height) { super(); this.width = width; this.height = height; } @Override public double area() { return width*height; } @Override public double perimeter() { return 2*(width+height); } @Override public String toString() { return "MyRectangle [width=" + width + ", height=" + height + ", area=" + area() + ", perimeter=" + perimeter() + "]"; } }
⑶、類MyTriangle:
實現Shape接口,並有以下屬性和方法:
① 屬性
x,y,z: double型,表示三角形的三條邊
s: 周長的1/2(注:求三角形面積公式為,
s=(x+y+z)/2 ,開方可用Math.sqrt(double)方法)
② 方法
MyTriangle(double x, double y, double z):構造函數,給三條邊和s賦初值。
toString():輸出矩形的描述信息,如“three sides:3.0,4.0,5.0,perimeter=12.0,area=6.0”
class MyTriangle implements ShapeArea { private double x; private double y; private double z; public MyTriangle(double x, double y, double z) { super(); this.x = x; this.y = y; this.z = z; } @Override public double area() { double s=perimeter(); return Math.sqrt(s*(s-x)*(s-y)*(s-z)); } /* * 覆蓋了父類application的perimeter函數 */ @Override public double perimeter() { return 0.5*(x+y+z); } @Override public String toString() { return "MyTriangle [x=" + x + ", y=" + y + ", z=" + z + ", area=" + area() + ", perimeter=" + perimeter() + "]"; } }
⑷、Test類作為主類要完成測試功能
①生成MyRectangle對象
② 調用對象的toString方法,輸出對象的描述信息
public class test { public static void main(String[] args) { ShapeArea sa; sa=new MyRectangle(10, 20.5); System.out.println(sa.toString()); sa=new MyTriangle(3,4,5); System.out.println(sa.toString()); } }
結果

6、定義一個接口CanFly,描述會飛的方法public void fly();
interface CanFly { public void fly(); }
分別定義類飛機和鳥,實現CanFly接口。
//飛機類 public class airplane implements CanFly { @Override public void fly() { System.out.println("我是飛機我會飛"); } } //鳥類 public class bird implements CanFly { @Override public void fly() { System.out.println("我是鳥我會飛"); } }
定義一個測試類,測試飛機和鳥,在main方法中創建飛機對象和鳥對象,再定義一個makeFly()方法,其中讓會飛的事物飛。並在main方法中調用該方法,讓飛機和鳥起飛。
public class test { public static void main(String[] args) { CanFly c1=new airplane(); CanFly c2=new bird(); makeFly(c1); makeFly(c2); } private static void makeFly(CanFly c) { c.fly(); } }
結果


