1.格式:
abstract class 類名 {}
2.特點:
1)抽象類和抽象方法必須用abstract關鍵字修飾
2)抽象類中不一定有抽象方法,但是有抽象方法的類必須定義爲抽象類
3)抽象類不能實例化
因爲它不是具體的。
抽象類有構造方法,但是不能實例化?構造方法的作用是什麼呢?
用於子類訪問父類數據的初始化
4)抽象的子類
a:如果不想重寫抽象方法,該子類是一個抽象類。
b:重寫所有的抽象方法,這個時候子類是一個具體的類。
抽象類的實例化其實是靠具體的子類實現的。是多態的方式。
3.抽象類的成員特點:
成員變量:既可以是變量,也可以是常量。
構造方法:有。 用於子類訪問父類數據的初始化。
成員方法:既可以是抽象的,也可以是非抽象的。
抽象類的成員方法特性:
A:抽象方法 強制要求子類做的事情。
B:非抽象方法 子類繼承的事情,提高代碼複用性。
4.abstract不能和哪些關鍵字共存?
1)private 衝突
2)final 衝突
3)Static 無意義
5.接口特點
接口用關鍵字interface表示
格式:interface 接口名 {}
類實現接口用implements表示
格式:class 類名 implements 接口名 {}
6.接口成員特點
1)成員變量: 只能是常量
默認修飾符 public static final
2)構造方法:沒有
因爲接口主要是擴展功能的,而沒有具體存在
3)成員方法: 只能是抽象方法
默認修飾符 public abstract
所有的類都默認繼承自一個類:Object。
類Object 是類層次結構的根類。每個類都使用 Object 作爲超類。
7.類與類,類與接口以及接口與接口的關係
1)類與類
繼承關係,只能單繼承,但是可以多層繼承
2)類與接口
實現關係,可以單實現,也可以多實現。還可以在繼承一個類的同時實現多個接口
3)接口與接口
繼承關係,可以單繼承,也可以多繼承
8.抽象類和接口的區別
1)成員區別
抽象類 變量,常量;有抽象方法;抽象方法,非抽象方法
接口 常量;抽象方法
2)關係區別
類與類 繼承,單繼承
類與接口 實現,單實現,多實現
接口與接口 繼承,單繼承,多繼承
3)設計理念區別
抽象類 被繼承體現的是:”is a”的關係。共性功能
接口 被實現體現的是:”like a”的關係。擴展功能
9.形式參數和返回值問題
返回值類型:
1)基本類型:
2)引用類型:
類作爲返回值:返回的是該類的對象
抽象類作爲返回值:返回的是該抽象類的子類對象
接口作爲返回值:返回的是該接口的實現類的對象
10.鏈式編程。
每次調用完畢方法後,返回的是一個對象。
11.今天練習過程中出現的錯誤:有些是經常出現的錯誤,比如:變量引用方法時方法名後面沒有加括號、全角逗號、寫太快this.name = name只寫了一半等。
/*用貓狗案例,練習抽象類*/
abstract class Animal
{
private String name;
private int age;
public Animal(){}
public Animal(String name,int age){
this.name = name;
this.age = age;
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
public abstract void eat();//抽象方法,注意後面不用{}。
public void show(){
System.out.println("名字叫:" + name + ",年齡爲:" + age);
/*System.out.println("名字叫:" + name + ",年齡爲:" + age + this.eat());//錯誤: 此處不允許使用 '空' 類型.原意是想把姓名年齡和行爲一起打印出來,但忽略了eat()本身就是個打印方法,返回值類型爲空*/
}
}
class Dog extends Animal
{
public Dog(){}
public Dog(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("愛吃肉骨頭");
}
}
class Cat extends Animal
{
public Cat(){}
public Cat(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("愛吃魚");
}
public void playGame(){
System.out.println("玩毛線,抓蝴蝶");
}
}
class Test1
{
public static void main(String[] args){
Animal a = new Dog("阿黃",2);
a.show();
a.eat();
a.setName("小黑");
a.setAge(2);
a.show();
a.eat();
Animal b = new Cat("小花",3);
b.show();
b.eat();
/*嘗試b.playGame();這個編譯時就不會通過,因爲多態編譯是先看左邊,Animal類的a無法調用Cat類方法playGame()。*/
Cat c = (Cat)b;
c.show();
c.eat();
c.playGame();//強轉成子類Cat類就可以了。
}
}
/*
貓狗案例,加入跳高的額外功能
分析:從具體到抽象
貓:
姓名,年齡
吃飯,睡覺
狗:
姓名,年齡
吃飯,睡覺
由於有共性功能,所以,我們抽取出一個父類:
動物:
姓名,年齡
吃飯();
睡覺(){}
貓:繼承自動物
狗:繼承自動物
跳高的額外功能是一個新的擴展功能,所以我們要定義一個接口
接口:
跳高
部分貓:實現跳高
部分狗:實現跳高
實現;
從抽象到具體
使用:
使用具體類
*/
//定義跳高接口
interface Jumpping{
public abstract void jump();
}
interface Counting{//作爲練習自己多添加了一個數數功能
public abstract void count();
}
abstract class Animal
{
private String name;
private int age;
//構造方法
public Animal(){}
public Animal(String name,int age){
this.name = name;/*this.name;//錯誤:不是語句。賦值語句忘寫了後半句*/
this.age =age;/*this.age;//錯誤:不是語句*/
}
//定義抽象方法,吃飯
public abstract void eat();
//定義非抽象方法,睡覺
public void sleep(){
System.out.println("睡覺覺");
}
//set\get方法
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age = age;
}
public int getAge(){
return age;
}
}
//定義貓類
class Cat extends Animal{
public Cat(){}
public Cat(String name, int age){
super(name,age);
}
public void eat(){
System.out.println("貓吃魚");
}
}
//定義狗類
class Dog extends Animal{
public Dog(){}
public Dog(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("狗吃肉");
}
}
//跳高功能的貓
class JumpCat extends Cat implements Jumpping{
public JumpCat(){}
public JumpCat(String name,int age){
super(name,age);/*super(nam,age);//打字要細心*/
}
public void jump(){
System.out.println("它是會跳高的小貓咪");
}
}
//會表演跳高和數數的狗狗
class ShowDog extends Dog implements Jumpping,Counting{ /*同時實現兩個功能。類與接口可以多個實現*/
public ShowDog(){}
public ShowDog(String name,int age){
super(name,age);
}
public void jump(){
System.out.println("它是會跳高的小狗狗");
}
public void count(){
System.out.println("它是會數數的狗狗");
}
}
//主方法
class InterfaceDemo
{
public static void main(String[] args){
JumpCat jc = new JumpCat("小白",4);
jc.eat();
jc.sleep();
System.out.println("它的名字叫"+jc.getName()+",它的年齡是:"+jc.getAge());
jc.jump();
ShowDog sg = new ShowDog();/*ShowDog sg = new ShowDog;//調用方法和定義類時經常會忘記寫括號,要留神*/
sg.setName("小黑");
sg.setAge(5);
sg.eat();
sg.sleep();
System.out.println("它的名字叫"+sg.getName()+",它的年齡"+sg.getAge());
/*System.out.println("它的名字叫"+sg.getName()+"它的年齡"+sg.getAge));//錯誤找不到符號。getAge方法的括弧又忘了*/
sg.jump();
sg.count();
}
}
/*
教練和運動員案例(學生分析然後講解)
乒乓球運動員和籃球運動員。
乒乓球教練和籃球教練。
爲了出國交流,跟乒乓球相關的人員都需要學習英語。
請用所學知識:
分析,這個案例中有哪些抽象類,哪些接口,哪些具體類。
*/
//建立學英語功能接口
interface SpeakEnglish{
public abstract void speak();/*public abstract void speak(){};//錯誤:接口抽象方法不能帶有主體*/
}
//建立人抽象類
abstract class Person{/*abstract Person // 只顧寫abstract,忽略了class*/
private String name;
private int age;
public Person(){}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public abstract void eat();
public void sleep(){
System.out.println("人人都睡覺");
}
public void setName(String name){
this.name = name;
}
public String getName(){
return name;
}
public void getAge(int age){
this.age = age ;/*this.age;//錯誤:不是語句。忘記賦值*/
}
public int getAge(){
return age;
}
}
//運動員抽象類
abstract class Player extends Person{
public Player(){}
public Player(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("喝豆奶吃雞腿");
}
public abstract void study();
}
//教練抽象類
abstract class Coath extends Person{
public Coath(){}
public Coath(String name,int age){
super(name,age);
}
public void eat(){
System.out.println("喝牛奶吃牛排");
}
public abstract void teach();
}
//乒乓球運動員具體類
class PingPangPlayer extends Player implements SpeakEnglish{
public PingPangPlayer(){}
public PingPangPlayer(String name,int age){
super(name,age);
}
public void study(){
System.out.println("學習揮拍發球接球");
}
public void speak(){
System.out.println("會說英語");/* System.out.println("會說英語") //忘記分號*/
}
}
//籃球運動員具體類
class BasketBallPlayer extends Player{
public BasketBallPlayer(){}
public BasketBallPlayer(String name,int age){
super(name,age);
}
public void study(){
System.out.println("學習運球傳球投籃");
}
}
//乒乓球教練具體類
class PingPangCoath extends Coath implements SpeakEnglish{
public PingPangCoath(){}
public PingPangCoath(String name,int age){
super(name,age);
}
public void teach(){
System.out.println("教授握拍調球的方法");
}
public void speak(){
System.out.println("會說英語");
}
}
//籃球教練具體類
class BasketBallCoath extends Coath{
public BasketBallCoath(){}
public BasketBallCoath(String name,int age){
super(name,age);
}
public void teach(){
System.out.println("教授投籃及攻防戰術");
}
}
//主方法
class InterfaceDemo2
{
public static void main(String[] args)
{
PingPangPlayer ppp = new PingPangPlayer("張繼科",28);/*PingPangPlayer("張繼科",28);//錯誤:中文逗號*/
System.out.println("這個運動員叫:" + ppp.getName() + "年齡:" + ppp.getAge());
ppp.eat();
ppp.sleep();
ppp.speak();
ppp.study();
System.out.println("---------------------");
PingPangCoath ppc = new PingPangCoath("劉國樑",40);
System.out.println("這個教練員叫:" + ppc.getName() + "年齡:" + ppc.getAge());
ppc.eat();
ppc.sleep();
ppc.speak();
ppc.teach();
System.out.println("---------------------");
BasketBallCoath bbc = new BasketBallCoath("宮魯鳴",50);
System.out.println("這個教練員叫:" + bbc.getName() + "年齡:" + bbc.getAge());
bbc.eat();
bbc.sleep();
bbc.teach();
System.out.println("---------------------");
BasketBallPlayer bbp = new BasketBallPlayer("王治郅",38);
System.out.println("這個運動員叫:" + bbp.getName() + "年齡:" + bbp.getAge());
bbp.eat();
bbp.sleep();
bbp.study();
System.out.println("---------------------");
SpeakEnglish p = new PingPangPlayer();
p.speak();
}
}