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:把面向物件部分的總結看一遍。準備後面使用。
有問題記錄下來問我