這篇博客總結了半天,希望自己以後返回來看的時候理解更深刻,也希望可以起到幫助初學者的作用. 轉載請註明 出自 : "luogg的博客園" , 抽象 一種專門用來做父類,被繼承的. (模板) 格式: abstract class 抽象類名{ 屬性; 普通方法; 訪問許可權 abstract 返回值類型 ...
這篇博客總結了半天,希望自己以後返回來看的時候理解更深刻,也希望可以起到幫助初學者的作用.
轉載請註明 出自 : luogg的博客園 ,
抽象
一種專門用來做父類,被繼承的. (模板)
格式:
abstract class 抽象類名{
屬性;
普通方法;
訪問許可權 abstract 返回值類型 方法名稱([形參]);//抽象方法,無方法體
}
抽象類中, 不寫訪問許可權的時候, 預設是default, 不同於介面中的預設(介面方法預設被public abstract 修飾), 子類在繼承抽象類時候, 需要重寫抽象類中方法, 修飾符可以預設不寫(default)或者寫public , 但在介面中重寫時必須為public
抽象類的定義及使用:
1, 定義父類為抽象類,並定義沒有方法體的抽象方法
2, 子類繼承抽象類, 並重寫父類的抽象方法,寫入方法體,去掉abstract
使用抽象類註意事項:
1, 抽象類本身不可以創建對象, 因為它不可以被實例化,即不能構造一個該類的對象.
2, 抽象類有構造方法, 在子類實例化前也會預設的調用它的無參構造方法, 只要是類, 都有構造方法
3, 抽象類中不一定要有抽象方法,但是有抽象方法的類, 一定要被聲明為抽象類,不然編譯不通過
4, abstract只能修飾類和方法
abstract 不能用來修飾屬性, 構造器, 不能與private , final , static 共用
- 屬性不能被覆蓋,重寫,
- 構造器不能被重寫
- private只能在本類中調用,不能被繼承,不能被重寫
- fianl修飾方法,不能被重寫 , 修飾類, 不能被繼承
抽象類與普通類的區別
介面
概念
介面可以理解為一種特殊的抽象類, 對行為的抽象, 由全局常量和公有抽象方法組成 , 介面的作用是用來被實現的(implement) , 介面屬於複合類型,
定義
[訪問修飾符] interface I介面名{
屬性(全局常量,預設被static final修飾);
抽象的方法(沒有方法體,方法預設被public abstract修飾);
}
註意事項:
1, 子類實現介面,重寫方法的時候,修飾符必須加public,當介面中用預設的時候,因為介面方法預設是public+abstract修飾的
2, 介面沒有構造方法,沒有辦法創建對象
3, 介面名字必須以大寫I開頭
4, 介面的作用是為了彌補java中的單繼承,介面之間可以多extends,
5, 介面不可以繼承抽象類, 但是介面可以extends 多個介面, 抽象類可以implements介面,普通類可以implements多個介面
介面和抽象的混搭使用
當子類既要繼承抽象類 , 又要實現介面的時候, 先extends 抽象類, 然後再 implements 介面1,介面2..{}
public class Test2 {
public static void main(String[] args) {
P p1 = new P();
p1.tell2();
// static修飾的age,靜態全局常量,
System.out.println(I1.age);
System.out.println(I2.age);
System.out.println(I3.age);
p1.tell1("花花");
p1.tell1();
}
}
//定義一個抽象類
abstract class Abs1 implements I1,I2{//抽象類可以implements多個介面,但是不可以extends介面
String name;
// 抽象類可以有構造方法
Abs1() {
}
Abs1(String name){
}
abstract void tell1();
}
//定義介面
interface I1 extends I2,I3{//介面和介面之間可以多extends,但是介面不可以extends抽象類,介面不可以implements介面
int age = 10;//不可以使用int age;因為預設是final
/*I1(){
//Interfaces cannot have constructors
}*/
// 定義介面的抽象類
void tell2();
}
interface I2{
int age = 20;
void tell3();
}
interface I3{
int age = 30;
void tell4();
}
class P extends Abs1 implements I1,I2,I3{
// 抽象類可以有構造方法
void tell1(String name) {
System.out.println("抽象方法被執行...");
}
public void tell2() {
System.out.println("介面1的方法被執行...");
}
public void tell3() {
System.out.println("介面2的方法被執行...");
}
public void tell4() {
System.out.println("介面3的方法被執行...");
}
@Override
void tell1() {
System.out.println("抽象方法被執行...");
}
抽象類和介面的區別
多態
概念
一個事物的多種表現形態,多種狀態.
1, 方法的重寫與重載
2, 子類對象的多態性 Person p1 = new Man();
3, 父類的引用指向子類對象
多態的實現
向上轉型
- 向上轉型,可以調用父類方法也可以調用本類方法
- 但是父類和子類有相同方法sleep的時候,調用時候會調用子類方法
向下轉型(使用的不多)
instanceof關鍵字
表示運算符前面的這個對象是不是運算符後面的類的實例
對象 instanceof 類
只要是本類和本類的父類,都是返回true, 包括Object類
虛方法的調用
1, 當子類覆寫了父類中的方法,在發生多態的時候,調用的是子類的方法
2, 通過父類的引用指向子類的對象實體, 當調用方法時, 實際執行的是子類重寫父類的方法
使用多態
public class TeachTest {
public static void main(String[] args) {
//實例化一個新的數學老師,
//向上轉型,可以調用父類方法也可以調用本類方法
//但是父類和子類有相同方法sleep的時候,調用時候會調用子類方法
Teacher t1 = new MathTeacher();//向上轉型
t1.teach();
t1.sleep();
t1.speak();
//強制將Teacher 轉換為MathTeacher(向下轉型)
MathTeacher mt = (MathTeacher)t1;
mt.teach();
//使用封裝了的方法
EnglishTeacher e = new EnglishTeacher();
TeacherAll(e);
System.out.println(e instanceof Teacher);
}
/*
如果要調用類的方法,先實例化一個類,然後分別調用
MathTeacher mt = new MathTeacher();
mt.teach();
mt.sleep();
ChineseTeacher ct = new ChineseTeacher();
ct.teach();
ct.sleep();
發現這樣比較麻煩,向上抽取,定義一個新的工具類TeachTest的TeacherAll方法,將方法封裝進去
*/
public static void TeacherAll(Teacher t) {
t.sleep();
t.teach();
}
}
abstract class Teacher{
abstract void teach();
void sleep() {
System.out.println("老師在睡覺...");
}
void speak() {
System.out.println("老師正在說話...");
}
}
class MathTeacher extends Teacher{
void teach() {
System.out.println("數學老師在講數學...");
}
void sleep() {
System.out.println("數學老師正在躺著睡覺...");
}
}
class EnglishTeacher extends Teacher{
void teach() {
System.out.println("英語老師在教英語...");
}
void sleep() {
System.out.println("英語老師睡在沙發上...");
}
}
運行結果: