1. 程式人生 > >day10 01_類,抽象類,介面的綜合小練習,02_形式引數和返回值的問題深入研究,03_包的概述和講解,04_修飾符的概述和總結,05_內部類概述和講解

day10 01_類,抽象類,介面的綜合小練習,02_形式引數和返回值的問題深入研究,03_包的概述和講解,04_修飾符的概述和總結,05_內部類概述和講解

01_類,抽象類,介面的綜合小練習

/*
教練和運動員案例(學生分析然後講解)
乒乓球運動員和籃球運動員。
乒乓球教練和籃球教練。
為了出國交流,跟乒乓球相關的人員都需要學習英語。
請用所學知識:
分析,這個案例中有哪些抽象類,哪些介面,哪些具體類。

整個分析過程,我是通過畫圖講解的。
*/
//定義一個說英語的介面
interface SpeakEnglish {
//說英語
public abstract void speak();
}


//定義人的抽象類
abstract class Person {
private String name;
private int age;

public Person() {}


public Person(String name,int age) {
this.name = name;
this.age = age;
}

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;
}

//睡覺
public void sleep() {
System.out.println("人都是要睡覺的");
}

//吃飯
public abstract void eat();
}


//定義運動員抽象類
abstract class Player extends Person {
public Player() {}

public Player(String name,int age) {
super(name,age);
}

//學習
public abstract void study();
}


//定義教練抽象類
abstract class Coach extends Person {
public Coach() {}

public Coach(String name,int age) {
super(name,age);
}

//教
public abstract void teach();
}


//定義乒乓球運動員具體類
class PingPangPlayer extends Player implements SpeakEnglish {
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("乒乓球運動員說英語");
}
}


//定義籃球運動員具體類
class BasketballPlayer extends Player {
public BasketballPlayer(){}

public BasketballPlayer(String name,int age) {
super(name,age);
}

//吃
public void eat() {
System.out.println("籃球運動員吃牛肉,喝牛奶");
}

//學習
public void study() {
System.out.println("籃球運動員學習如何運球和投籃");
}
}


//定義乒乓球教練具體類
class PingPangCoach extends Coach implements SpeakEnglish {
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("乒乓球教練說英語");
}
}


//定義籃球教練具體類
class BasketballCoach extends Coach {
public BasketballCoach(){}

public BasketballCoach(String name,int age) {
super(name,age);
}

//吃
public void eat() {
System.out.println("籃球教練吃羊肉,喝羊奶");
}

//教
public void teach() {
System.out.println("籃球教練教如何運球和投籃");
}
}


class InterfaceDemo {
public static void main(String[] args) {
//測試運動員(乒乓球運動員和籃球運動員)
//乒乓球運動員
PingPangPlayer ppp = new PingPangPlayer();
ppp.setName("王浩");
ppp.setAge(33);
System.out.println(ppp.getName()+"---"+ppp.getAge());
ppp.eat();
ppp.sleep();
ppp.study();
ppp.speak();
System.out.println("----------------");
//通過帶參構造給資料(留給你們)

//籃球運動員
BasketballPlayer bp = new BasketballPlayer();
bp.setName("姚明");
bp.setAge(34);
System.out.println(bp.getName()+"---"+bp.getAge());
bp.eat();
bp.sleep();
bp.study();
//bp.speak(); //沒有該方法

//測試教練自己做
}

}

02_形式引數和返回值的問題深入研究

/*
形式引數:
基本型別(太簡單,不是我今天要講解的)
引用型別
類名:(匿名物件的時候其實我們已經講過了)需要的是該類的物件
抽象類:需要的是該抽象的類子類物件
介面
*/
abstract class Person {
public abstract void study();
}


class PersonDemo {
public void method(Person p) {//p; p = new Student();  Person p = new Student(); //多型
p.study();
}
}


//定義一個具體的學生類
class Student extends Person {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}


class PersonTest {
public static void main(String[] args) {
//目前是沒有辦法的使用的
//因為抽象類沒有對應的具體類
//那麼,我們就應該先定義一個具體類
//需求:我要使用PersonDemo類中的method()方法
PersonDemo pd = new PersonDemo();
Person p = new Student();
pd.method(p);
}

}


/*
返回值型別
基本型別:(基本型別太簡單,我不準備講解)
引用型別:
類:返回的是該類的物件
抽象類:返回的是該抽象類的子類物件
介面:
*/
abstract class Person {
public abstract void study();
}


class PersonDemo {
public Person getPerson() {
//Person p = new Student();
//return p;

return new Student();
}
}


class Student extends Person {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}


class PersonTest2 {
public static void main(String[] args) {
//需求:我要測試Person類中的study()方法
PersonDemo pd = new PersonDemo();
Person p = pd.getPerson(); //new Student();  Person p = new Student(); 多型
p.study();
}

}


/*
形式引數:
基本型別(太簡單,不是我今天要講解的)
引用型別
類名:(匿名物件的時候其實我們已經講過了) 需要的是該類的物件
抽象類:
介面
*/
class Student {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}


class StudentDemo {
public void method(Student s) { //ss; ss = new Student();  Student s = new Student();
s.study();
}
}


class StudentTest {
public static void main(String[] args) {
//需求:我要測試Student類的study()方法
Student s = new Student();
s.study();
System.out.println("----------------");

//需求2:我要測試StudentDemo類中的method()方法
StudentDemo sd = new StudentDemo();
Student ss = new Student();
sd.method(ss);
System.out.println("----------------");

//匿名物件用法
new StudentDemo().method(new Student());
}

}


/*
返回值型別
基本型別:(基本型別太簡單,我不準備講解)
引用型別:
類:返回的是該類的物件
抽象類:
介面:
*/
class Student {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}


class StudentDemo {
public Student getStudent() {
//Student s = new Student();
//Student ss = s;

//Student s = new Student();
//return s;
return new Student();
}
}


class StudentTest2 {
public static void main(String[] args) {
//需求:我要使用Student類中的study()方法
//但是,這一次我的要求是,不要直接建立Student的物件
//讓你使用StudentDemo幫你建立物件
StudentDemo sd = new StudentDemo();
Student s = sd.getStudent(); //new Student(); Student s = new Student();
s.study();
}

}


/*
鏈式程式設計。
每次呼叫完畢方法後,返回的是一個物件。
*/
class Student {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}


class StudentDemo {
public Student getStudent() {
return new Student();
}
}


class StudentTest3 {
public static void main(String[] args) {
//如何呼叫的呢?
StudentDemo sd = new StudentDemo();
//Student s = sd.getStudent();
//s.study();

//大家注意了
sd.getStudent().study();
}

}


/*
形式引數:
基本型別(太簡單,不是我今天要講解的)
引用型別
類名:(匿名物件的時候其實我們已經講過了)需要的是該類的物件
抽象類:需要的是該抽象的類子類物件
介面:需要的是該介面的實現類物件
*/
//定義一個愛好的介面
interface Love {
public abstract void love();
}


class LoveDemo {
public void method(Love l) { //l; l = new Teacher();  Love l = new Teacher(); 多型
l.love();
}
}


//定義具體類實現介面
class Teacher implements Love {
public void love() {
System.out.println("老師愛學生,愛Java,愛林青霞");
}
}


class TeacherTest {
public static void main(String[] args) {
//需求:我要測試LoveDemo類中的love()方法
LoveDemo ld = new LoveDemo();
Love l = new Teacher();
ld.method(l);
}

}


/*
返回值型別
基本型別:(基本型別太簡單,我不準備講解)
引用型別:
類:返回的是該類的物件
抽象類:返回的是該抽象類的子類物件
介面:返回的是該介面的實現類的物件
*/
//定義一個愛好的介面
interface Love {
public abstract void love();
}


class LoveDemo {
public Love getLove() {
//Love l = new Teacher();
//return l;

return new Teacher();
}
}


//定義具體類實現介面
class Teacher implements Love {
public void love() {
System.out.println("老師愛學生,愛Java,愛林青霞");
}
}


class TeacherTest2 {
public static void main(String[] args) {
//如何測試呢?
LoveDemo ld = new LoveDemo();
Love l = ld.getLove(); //new Teacher(); Love l = new Teacher(); 多型
l.love();
}

}


03_包的概述和講解

/*
Test類,測試


導包:
格式:import 包名;
這種方式匯入是到類的名稱。
注意:我們用誰就導誰。

面試題:
package,import,class有沒有順序關係(在 .java檔案中出現的順序)?
有。
package > import > class

Package:只能有一個
import:可以有多個
class:可以有多個,以後建議是一個
*/
package cn.itcast;


import com.liuyi.Demo;


class Test {
public static void main(String[] args) {
//Demo d = new Demo();
/*
com.liuyi.Demo d = new com.liuyi.Demo();
System.out.println(d.sum(10,20));

com.liuyi.Demo d2 = new com.liuyi.Demo();
System.out.println(d2.sum(10,20));

com.liuyi.Demo d3 = new com.liuyi.Demo();
System.out.println(d3.sum(10,20));

com.liuyi.Demo d4 = new com.liuyi.Demo();
System.out.println(d4.sum(10,20));
*/

Demo d = new Demo();
System.out.println(d.sum(10,20));
}
}


/*
第一個問題:找不到Demo

第二個問題:程式包com.liuyi不存在

第三個問題: Demo在com.liuyi中不是公共的; 無法從外部程式包中對其進行訪問

*/


/*
Demo類,求和
*/
package com.liuyi;


public class Demo {
public int sum(int a,int b) {
return a + b;
}

}


04_修飾符的概述和總結

/*
修飾符:
許可權修飾符:private,預設的,protected,public
狀態修飾符:static,final
抽象修飾符:abstract

類:
許可權修飾符:預設修飾符,public
狀態修飾符:final
抽象修飾符:abstract

用的最多的就是:public

成員變數:
許可權修飾符:private,預設的,protected,public
狀態修飾符:static,final

用的最多的就是:private

構造方法:
許可權修飾符:private,預設的,protected,public

用的最多的就是:public

成員方法:
許可權修飾符:private,預設的,protected,public
狀態修飾符:static,final
抽象修飾符:abstract

用的最多的就是:public

除此以外的組合規則:
成員變數:public static final
成員方法:public static 
         public abstract
 public final

*/
//此處不允許使用修飾符private
//此處不允許使用修飾符protected
//此處不允許使用修飾符static
public class Demo {
//成員變數
private int x = 10;
int y = 20;
protected int z = 30;
public int a = 40;
public final int b = 50;
public static int c = 60;
public static final int d = 70;
//此處不允許使用修飾符abstract
//abstract int e = 80;

//構造方法
private Demo(){}

Demo(String name){}

protected Demo(String name,int age) {}

public Demo(String name,int age,String address) {}

//此處不允許使用修飾符static
//public static Demo(){}
//此處不允許使用修飾符final
//public final Demo() {}
//此處不允許使用修飾符abstract
//public abstract Demo(){}

//成員方法
//static void show() {}
//abstract void show();
//final void show(){}

}


/*
許可權修飾符:
本類      同一個包下(子類和無關類)               不同包下(子類)    不同包下(無關類)
private          Y
預設         Y Y
protected Y Y Y
public Y Y Y Y
*/
package com.liuyi;


public class Father {
private void show() {
System.out.println("show");
}

void show2() {
System.out.println("show2");
}

protected void show3() {
System.out.println("show3");
}

public void show4() {
System.out.println("show4");
}

public static void main(String[] args) {
Father f = new Father();
f.show();
f.show2();
f.show3();
f.show4();
}

}


package com.liuyi;


public class Son extends Father {
public static void main(String[] args) {
Father f = new Father();
//f.show();
f.show2();
f.show3();
f.show4();
System.out.println("--------------");

Son s = new Son();
//s.show();
s.show2();
s.show3();
s.show4();
}

}


package cn.qx;


import com.liuyi.Father;


public class Son2 extends Father {
public static void main(String[] args) {
Father f = new Father();
//f.show();
//f.show2();
//f.show3();
f.show4();
System.out.println("--------------");

Son2 s = new Son2();
//s.show();
//s.show2();
s.show3();
s.show4();
}

}


package com.liuyi;


public class Test {
public static void main(String[] args) {
Father f = new Father();
//f.show();
f.show2();
f.show3();
f.show4();
}

}


package cn.qx;


import com.liuyi.Father;


class Test2 {
public static void main(String[] args) {
Father f = new Father();
//f.show();
//f.show2();
//f.show3();
f.show4();
}

}


05_內部類概述和講解

/*
內部類概述:
把類定義在其他類的內部,這個類就被稱為內部類。
舉例:在類A中定義了一個類B,類B就是內部類。

內部的訪問特點:
A:內部類可以直接訪問外部類的成員,包括私有。
B:外部類要訪問內部類的成員,必須建立物件。

*/
class Outer {
private int num = 10;

class Inner {
public void show() {
System.out.println(num);
}
}

public void method() {
//找不到符號
//show();

Inner i = new Inner();
i.show();

}

}


class InnerClassDemo {
public static void main(String[] args) {

}

}


/*
內部類位置
成員位置:在成員位置定義的類,被稱為成員內部類。
區域性位置:在區域性位置(即成員函式內部)定義的類,被稱為區域性內部類。


成員位置:在成員位置定義的類,被稱為成員內部類。

*/
class Outer {
private int num = 10;


//成員位置
/*
class Inner {

}
*/



public void method() {
//區域性位置
class Inner {

}
}
}


class InnerClassDemo2 {
public static void main(String[] args) {

}

}


/*
成員內部類:
如何直接訪問內部類的成員。
外部類名.內部類名 物件名 = 外部類物件.內部類物件;
*/
class Outer {
private int num = 10;

class Inner {
public void show() {
System.out.println(num);
}
}
}


class InnerClassDemo3 {
public static void main(String[] args) {
//需求:我要訪問Inner類的show()方法
//Inner i = new Inner();
//i.show();

//格式:外部類名.內部類名 物件名 = 外部類物件.內部類物件;
Outer.Inner oi = new Outer().new Inner();
oi.show();
}

}


/*
成員內部類的修飾符:
private 為了保證資料的安全性
static 為了方便訪問資料

注意:靜態內部類訪問的外部類資料必須用靜態修飾。

案例:我有一個人(人有身體,身體內有心臟。)

class Body {
private class Heart {
public void operator() {
System.out.println("心臟搭橋");
}
}

public void method() {
if(如果你是外科醫生) {
Heart h = new Heart();
h.operator();
}
}
}

按照我們剛才的講解,來使用一下
Body.Heart bh = new Body().new Heart();
bh.operator();
//加了private後,就不能被訪問了,那麼,怎麼玩呢?
Body b =  new Body();
b.method();
*/
class Outer {
private int num = 10;
private static int num2 = 100;

//內部類用靜態修飾是因為內部類可以看出是外部類的成員
public static class Inner {

public void show() {          //靜態類中的方法可以是非靜態的嗎?

//System.out.println(num);
System.out.println(num2);   //靜態類中的方法只能訪問靜態資料
}


public static void show2() {
//System.out.println(num);
System.out.println(num2);   //靜態類中的方法只能訪問靜態資料
}
}
}


class InnerClassDemo4 {
public static void main(String[] args) {
//使用內部類
// 限定的新靜態類
//Outer.Inner oi = new Outer().new Inner();
//oi.show();
//oi.show2();

//成員內部類被靜態修飾後的訪問方式是:
//格式:外部類名.內部類名 物件名 = new 外部類名.內部類名();
Outer.Inner oi = new Outer.Inner();
oi.show();
oi.show2();

//show2()的另一種呼叫方式, 靜態類中的靜態方法可以直接以類名呼叫
Outer.Inner.show2();
}

}


/*
區域性內部類
A:可以直接訪問外部類的成員
B:在區域性位置,可以建立內部類物件,通過物件呼叫內部類方法,來使用區域性內部類功能

面試題:
區域性內部類訪問區域性變數的注意事項?

A:區域性內部類訪問區域性變數必須用final修飾

B:為什麼呢?
區域性變數是隨著方法的呼叫而呼叫,隨著呼叫完畢而消失。
而堆記憶體的內容並不會立即消失。所以,我們加final修飾。
加入final修飾後,這個變數就成了常量。既然是常量。你消失了。
我在記憶體中儲存的是資料20,所以,我還是有資料在使用。
*/
class Outer {
private int num  = 10;

public void method() {
//int num2 = 20;
final int num2 = 20;
class Inner {
public void show() {
System.out.println(num);
/ /從內部類中訪問本地變數num2; 需要被宣告為最終型別
System.out.println(num2);//20

}
}

//System.out.println(num2);

Inner i = new Inner();
i.show();
}
}


class InnerClassDemo5 {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}

}


/*
匿名內部類
就是內部類的簡化寫法。


前提:存在一個類或者介面
這裡的類可以是具體類也可以是抽象類。

格式:
new 類名或者介面名(){
重寫方法;
}

本質是什麼呢?
是一個繼承了該類或者實現了該介面的子類匿名物件。
*/
interface Inter {
public abstract void show();
public abstract void show2();
}


class Outer {
public void method() {
//一個方法的時候
/*
new Inter() {
public void show() {
System.out.println("show");
}
}.show();
*/

//二個方法的時候
/*
new Inter() {
public void show() {
System.out.println("show");
}

public void show2() {
System.out.println("show2");
}
}.show();

new Inter() {
public void show() {
System.out.println("show");
}

public void show2() {
System.out.println("show2");
}
}.show2();
*/

//如果我是很多個方法,就很麻煩了
//那麼,我們有沒有改進的方案呢?
Inter i = new Inter() { //多型
public void show() {
System.out.println("show");
}

public void show2() {
System.out.println("show2");
}
};

i.show();
i.show2();
}
}


class InnerClassDemo6 {
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}

}


/*
面試題:
要求請填空分別輸出30,20,10。

注意:
1:內部類和外部類沒有繼承關係。
2:通過外部類名限定this物件
Outer.this
*/
class Outer {
public int num = 10;
class Inner {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num);
System.out.println(this.num);
//System.out.println(new Outer().num);
System.out.println(Outer.this.num);
}
}
}
class InnerClassTest {
public static void main(String[] args) {
Outer.Inner oi = new Outer().new Inner();
oi.show();
}

}


/*
匿名內部類在開發中的使用
*/
interface Person {
public abstract void study();
}


class PersonDemo {
//介面名作為形式引數
//其實這裡需要的不是介面,而是該介面的實現類的物件
public void method(Person p) {
p.study();
}
}


//實現類
class Student implements Person {
public void study() {
System.out.println("好好學習,天天向上");
}
}


class InnerClassTest2 {
public static void main(String[] args) {
//測試
PersonDemo pd = new PersonDemo();
Person p = new Student();
pd.method(p);
System.out.println("--------------------");

//匿名內部類在開發中的使用
//匿名內部類的本質是繼承類或者實現了介面的子類匿名物件
pd.method(new Person(){
public void study() {
System.out.println("好好學習,天天向上");
}
});
}

}


/*
匿名內部類面試題:
按照要求,補齊程式碼
interface Inter { void show(); }
class Outer { //補齊程式碼 }
class OuterDemo {
public static void main(String[] args) {
 Outer.method().show();
 }
}
要求在控制檯輸出”HelloWorld”
*/
interface Inter { 
void show(); 
//public abstract
}


class Outer { 
//補齊程式碼
public static Inter method() {
//子類物件 -- 子類匿名物件
return new Inter() {
public void show() {
System.out.println("HelloWorld");
}
};
}
}


class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
/*
1:Outer.method()可以看出method()應該是Outer中的一個靜態方法。
2:Outer.method().show()可以看出method()方法的返回值是一個物件。
又由於介面Inter中有一個show()方法,所以我認為method()方法的返回值型別是一個介面。
*/
}

}


day9作業

1:final關鍵字可以幹什麼?有什麼特點?
最終的意思。可以修飾類,方法,變數。
它修飾類,類不能被繼承
它修飾方法,方法不能被重寫
它修飾變數,變數是常量


2:final關鍵字的面試題?
A:修飾區域性變數
基本型別:值不能改變
引用型別:地址值不能改變

B:初始化時機
定義的時候
構造方法中

3:多型是什麼,前提是什麼?
同一個物件在不同時刻表現出來的不同的狀態

A:有繼承或者實現關係
B:有方法的重寫
C:有父類或者父介面引用指向子類物件


4:多型中成員訪問的特點?
成員變數
編譯看左邊,執行看左邊
成員方法
編譯看左邊,執行看右邊
靜態方法
編譯看左邊,執行看左邊


5:多型的好處及弊端?如何解決多型的弊端?
好處:
維護性和擴充套件性

弊端:父類不能使用子類特有功能

如何解決呢?
A:建立子類物件。(在記憶體中會多了一個物件)
B:向下轉型


6:什麼是向上轉型?什麼是向下轉型?
子 - 父
父 - 子


7:多型練習
自己做

8:抽象類概述及其特點?
抽象類:繼承的時候,提取了多個方法,而有些方法不是每個子類都是一模一樣的實現,
       這個時候,就應該把這樣的方法不提供具體實現,而不提供具體實現的方法是一個抽象方法。
在一個類中,如果有抽象方法,該類必須定義為抽象類。

特點:
A:抽象類或者抽象方法由abstract修飾
B:抽象類中不一定有抽象方法,但是有抽象方法的類一定是抽象類
C:抽象類不能例項化
D:抽象類的子類
a:是抽象類
b:是具體類,就要重寫所有抽象方法

9:抽象類成員特點?
A:成員變數
有變數,有常量
B:構造方法
有。用於子類訪問父類資料的初始化
C:成員方法
有抽象方法,有非抽象方法


10:抽象類練習?


11:抽象類的小問題
A:一個類如果沒有抽象方法,可不可以定義為抽象類?如果可以,有什麼意義?
B:abstract不能和哪些關鍵字共存
final
static
private


12:介面的概述及其特點?
介面:某個繼承體系需要擴充套件功能的時候,就應該實現介面。

特點:
A:介面用interface修飾
B:類實現介面用implements修飾
C:介面不能例項化
D:介面的實現
a:抽象類
b:具體類,重寫介面中的所有抽象方法


13:介面的成員特點?
A:成員變數 靜態常量
B:成員方法 抽象的


14:抽象類和介面的區別?
A:成員區別
B:關係區別
C:設計理念區別
"is a"
"like a"


15:介面的練習?


16:案例
貓狗案例,加入跳高的額外功能
老師和學生案例,加入抽菸的額外功能

教練和運動員案例(學生分析然後講解)


day10作業

1:形式引數和返回值問題
形式引數
基本型別
引用型別
返回值型別
基本型別
引用型別


2:包的定義及注意事項


3:導包及注意事項


4:四種許可權修飾符及其特點


5:常見的修飾符及組合


6:內部類的概述及訪問特點


7:內部類的分類


8:匿名內部類的格式和應用及面試題


9:把面向物件部分的總結看一遍。準備後面使用。
  有問題記錄下來問我