Java基礎複習第九天:抽象類和介面
一 抽象類
1.由來
父類中的方法,如果所有子類都要重寫,那麼此時父類的方法體就失去了意義
那麼我們可以把方法體去掉,只留方法的宣告,這種只有方法宣告沒有方法實現的方法稱為
抽象方法
含有抽象方法的類一定是抽象類
子類如果繼承了抽象類,那麼必須重寫抽象類中所有的抽象方法,否則子類還是一個抽象類
2.抽象方法的格式;
public abstract 返回值型別 方法名(引數列表);
3.抽象類的格式:
public abstract class 類名{....}
4.注意事項:
a.抽象類是不能建立物件的!
b.抽象類是有構造方法,是給子類的構造方法呼叫的
(子類所有構造中都有預設使用super()呼叫父類的無參構造)
c.抽象類不一定包含抽象方法,但是包含抽象方法的類一定是抽象類
(抽象類可以有也可以沒有抽象方法)
d.抽象類子類 必須 重寫所有抽象方法,否則子類還是一個抽象類
5.抽象類中可以定義的成員
成員變數,成員方法,構造方法,抽象方法
6."抽象類"型別的多型形式
父類型別 變數名 = new 子類型別();
抽象型別類 變數名 = new 子類型別();
二.介面
1.什麼是介面
專業:介面是方法的集合(介面中只有方法,沒有普通的成員變數)
通俗:介面是一種極端的抽象類(在JDK1.7之前 所有的方法必須都是抽象方法)
(在JDK1.8時增加預設方法,靜態方法)
(在JDK1.9時增加私有方法)
2.定義介面的格式:
類: 使用關鍵字 class
列舉: 使用關鍵字enum
抽象類:使用abstract class
介面: 使用關鍵字interface
格式:
public interface 介面名{
//抽象方法(JDK1.7)
public abstract 返回值型別 方法名(引數列表);
//預設方法(JDK1.8)
public default 返回值型別 方法名(引數列表){
}
//靜態方法(JDK1.8)
public static 返回值型別 方法名(引數列表){
}
//私有方法(忽略)
private 返回值型別 方法名(引數列表){
}
}
3.介面的使用
a.介面也是不能建立物件的
實現類 實現(implements) 介面 (相當於子類 繼承 抽象類)
public class 實現類 implements 介面{
a.實現類需要重寫介面中所有的抽象方法,否則實現類變成一個抽象類
b.實現類可以選擇性重寫介面中預設方法
c.實現類對於介面的靜態方法沒有重寫這種說法
d.實現類對於介面的私有方法沒有重寫這種說法
}
4.介面的多實現
一個實現類 可以 實現多個介面
格式:
public class 實現類 implements 介面1,介面2,介面3....{
//1.必須重寫所有介面中的所有抽象方法
//2.可以選擇性重寫所有介面中的任何預設方法
//3.實現類對於介面的靜態方法沒有重寫這種說法
//4.實現類對於介面的私有方法沒有重寫這種說法
}
5.有同名的方法的介面多實現
public class 實現類 implements 介面1,介面2,介面3....{
//1.如果多個介面有同名的抽象方法,實現類只需要重寫一次
//2.如果多個介面中有同名的預設方法,實現類必須重寫一次
//3.靜態方法同名,沒有問題,哪個介面呼叫靜態方法,呼叫的就是那個介面中靜態方法
//4.私有方法同名,更加沒有問題,私有方法只能在當前介面中使用(如果你寫私有方法和靜態方法的時候報錯了,注意看 JDK版本)
}
6.繼承和實現
實際中,一個類 繼承 一個父類,同時實現多個介面
格式:
public class 類名 extends 父類 implements 介面1,介面2...{
//如果父類和介面都有相同的抽象方法,只需要寫一次即可
//父類有一個方法和介面的預設方法重名,可以不重寫,父類方法的優先順序高
}
7.介面和介面之間多繼承(瞭解即可)
格式:
public interface 子介面 extends 父介面1,父介面2...{
a.如果多個父介面中有相同抽象方法,子介面只有一個抽象方法
b.如果多個父介面中有相同的預設方法,子介面必須重寫一次
c.私有和靜態不需要關注
}
public class 類名 implements 子介面{
}
相當於
public class 類名 implements 父介面1,父介面2,...{
}
8.介面的其他成員
a.介面中無法定義變數,但是可以定義常量
public static final 資料型別 常量名 = 值;
三個修飾符可寫可以不寫,預設就有!!!!
b.介面中沒有構造方法,也不能建立物件
c.介面中,沒有靜態程式碼塊。
三.練習
一.
1:所有動物都有姓名,年齡;(成員變數要求私有)
2:所有動物都有自我介紹的方法(使用 show 方法表示),但是具體描述的內容不一樣;
狗類描述內容: 我叫 xxx,今年 xxx 歲了,我的病症是感冒;
貓類描述內容: 我叫 xxx,今年 xxx 歲了,我的病症是發燒;
3:編寫測試類,測試貓類和狗類的 show 方法;
效果:我叫阿強,今年3我的病症是感冒
我叫阿花,今年2我的病症是發燒
public abstract class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
abstract void show();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Animal{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
------------------------------------------------------------------------------------
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
void show() {
System.out.println("我叫"+this.getName()+",今年"+this.getAge()+"我的病症是發燒");
}
}
-------------------------------------------------------------------------------------
public class Dog extends Animal {
public Dog(){
}
public Dog(String name,int age){
super(name,age);
}
@Override
void show() {
System.out.println("我叫"+this.getName()+",今年"+this.getAge()+"我的病症是感冒");
}
}
---------------------------------------------------------------------------------------
public class TestDemo {
public static void main(String[] args) {
Dog d = new Dog("阿強",3);
d.show();
new Cat("阿花",2).show();
}
}
二.計算正方形和圓形的面積和周長
public abstract class Figure {
//static能和abstract同時使用,
//1.被static修飾的方法在與無static修飾的方法在記憶體中的位置不同
//2.被static修飾的方法、變數等屬於類,不是給子類來繼承的。
public abstract double area();
public abstract double Perimeter();
}
--------------------------------------------------------------------------------
public class Yuan extends Figure {
private double r;
public Yuan(double r) {
this.r = r;
}
public Yuan() {
}
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
@Override
public double area() {
return Math.PI*r*r;
}
@Override
public double Perimeter() {
return 2*Math.PI*r;
}
}
------------------------------------------------------------------------------------
public class Zheng extends Figure{
private double Long;
public Zheng() {
}
public double getLong() {
return Long;
}
public void setLong(double aLong) {
Long = aLong;
}
public Zheng(double aLong) {
this.Long = aLong;
}
@Override
public double area() {
return this.Long*4;
}
@Override
public double Perimeter() {
return this.Long*Long;
}
}
-----------------------------------------------------------------------------------
public class TestDome2 {
public static void main(String[] args) {
Zheng square = new Zheng(3.14);
System.out.println("正方形的周長是:"+square.Perimeter());
System.out.println("正方形的周長是:"+square.area());
Yuan circular = new Yuan(3.14);
System.out.println("正方形的周長是:"+circular.Perimeter());
System.out.println("正方形的周長是:"+circular.area());
}
}
三.自定義一個介面,包含預設方法 methodA 和抽象方法 methodB,通過實現類的物件這兩個方法;
效果:介面中的預設方法執行了...
實現類重寫的方法執行了...
public interface Father {
public default void methodA(){
System.out.println("介面中的預設方法執行了...");
}
public abstract void merhodB();
}
---------------------------------------------------------------------
public class MyClass implements Father {
@Override
public void merhodB() {
System.out.println("實現類重寫的方法執行了...");
}
public static void main(String[] args) {
MyClass test= new MyClass();
test.methodA();
test.merhodB();
}
}
四.使用實現類物件通過預設方法呼叫介面中的靜態方法完成列印10 次指定字串的功能;
效果:CCC CCC CCC CCC CCC CCC CCC CCC CCC CCC
public interface FaterInter04 {
default void print(String AAA){
//1 java類中的靜態方法 只能呼叫類中的靜態方法;
//2 java類中的非靜態方法可以呼叫類中的非靜態方法和靜態方法
printAAA(AAA);
}
static void printAAA(String AAA){
for (int i = 0; i < 10; i++) {
System.out.print(AAA+" ");
}
}
}
----------------------------------------------------------------------------
public class Zi04 implements FaterInter04 {
}
----------------------------------------------------------------------------
public class TestDome04 {
public static void main(String[] args) {
Zi04 zi04= new Zi04();
zi04.print("CCC");
}
}
五.
1:建立一個動物類,包含私有的姓名,getter/setter,構造方法,一個抽象的吃飯方法;
2:編寫貓類和狗類,繼承動物類,描述貓吃魚,狗吃骨頭,並以多型的
形式呼叫吃飯的方法;
效果:阿強是一隻貓,吃魚
阿花是一隻狗,吃骨頭
public abstract class Animal05 {
private String name;
public abstract String eat();
public Animal05(String name) {
this.name = name;
}
public Animal05() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
-----------------------------------------------------------------------------
public class Cat05 extends Animal05{
@Override
public String eat(){
return "吃魚";
}
public Cat05(String name){
super(name);
}
}
------------------------------------------------------------------------------
public class Dog05 extends Animal05 {
@Override
public String eat() {
return "吃骨頭";
}
public Dog05(String name) {
super(name);
}
public Dog05() {
}
}
-------------------------------------------------------------------------------
public class TestDemo05 {
public static void main(String[] args) {
Animal05 animal = new Dog05("阿花");
if(animal instanceof Dog05){
Dog05 d =(Dog05)animal;
System.out.println(d.getName()+"是一隻狗,"+d.eat());
} else{
Cat05 c = (Cat05)animal;
System.out.println(c.getName()+"是一隻貓,"+c.eat());
}
}
}
六.模擬購物車的新增商品,然後展示購物車詳情的功能;
商品包含:商品名稱,商品價格;
效果:商品{名字='小米8', 價格=2888.0}
商品{名字='錘子2s', 價格=2888.0}
商品{名字='華為10', 價格=2888.0}
public class article {
private String name;
private double price;
public article(String name, double price) {
this.name = name;
this.price = price;
}
public article() {
}
@Override
public String
toString() {
return "商品{" +
"名字='" + name + '\'' +
", 價格=" + price +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
---------------------------------------------------------------------------
import java.util.ArrayList;
public class Cart {
ArrayList<article> list = new ArrayList<>();
public static void main(String[] args) {
new Cart().add();
}
public void add(){
list.add(new article("小米8",2888.0));
list.add(new article("錘子2s",2888.0));
list.add(new article("華為10",2888.0));
print();
}
public void print(){
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i)); //重寫了toString
}
}
}