Java基礎學習第十天——修飾符與內部類
阿新 • • 發佈:2019-02-18
文件版本 | 開發工具 | 測試平臺 | 工程名字 | 日期 | 作者 | 備註 |
---|---|---|---|---|---|---|
V1.0 | 2016.03.02 | lutianfei | none |
形式引數和返回值問題
形式引數
:基本型別
引用型別
類
(匿名物件時有講):需要的是該類的物件
!抽象類
:需要的是該抽象類的子類物件
。介面
: 需要的是該介面的實現類物件
。
返回值
型別- 基本型別
- 引用型別
類
:返回的是該類的物件
抽象類
:返回的是該抽象類的子類物件
介面類
:返回的是該介面的實現類物件
Eg: 當
類
作為形式引數
的情況舉例:
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());
}
}
- Eg: 當
抽象類
作為形式引數的情況舉例:
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);
}
}
- Eg: 當
介面
作為形式引數的情況舉例:
//定義一個愛好的介面
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);
}
}
- Eg: 當
類
作為返回值的情況舉例:
class Student {
public void study() {
System.out.println("Good Good Study,Day Day Up");
}
}
class StudentDemo {
public Student getStudent() {
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();
}
}
- Eg: 當
抽象類
作為返回值的情況舉例:
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();
}
}
- Eg: 當
介面
作為返回值的情況舉例:
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();
}
}
鏈式程式設計
- 形式:
物件
.方法1()
.方法2()
….方法n()
- 每次呼叫方法完畢後,返回的是一個物件。
方法1
呼叫完畢後應該返回一個物件
,方法2
呼叫完畢後應該返回一個物件
,方法n
呼叫完畢後可能是物件,也可能不是物件。
/*
鏈式程式設計。
每次呼叫完畢方法後,返回的是一個物件。
*/
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();
}
}
包
包的概述
- 作用:對類進行分類管理,其實就是資料夾
- 包的劃分:
- 基本的劃分:按照模組和功能分。
- 高階的劃分:在具體專案中再說明。
包的定義及注意事項
- 定義包的格式
- package 包名;
- 多級包用
.
分開即可
注意事項:
- package語句必須是程式的第一條可執行(可被虛擬機器執行)的程式碼
- package語句在一個java檔案中只能有一個
- 如果沒有package,預設表示無包名
帶包的編譯和執行
- 手動式
- a:通過javac命令編譯該java檔案
- b:手動建立包名。
- c:將a步驟產生的類檔案放在b步驟的最底層包。
- d:帶包地址執行java命令
- 自動式
- javac編譯的時候帶上
-d
即可
- javac -d . HelloWorld.java
- javac編譯的時候帶上
- 手動式
導包
- 導包概述
- 不同包下的類之間的訪問,每次使用不同包下的類的時候,都需要加包的全路徑。方便起見,java提供了導包的功能。
- 導包格式
- import 包名;
注意:
- 這種方式匯入是到類的名稱。
- 雖然可以最後寫
*
,但是不建議。
package,import,class有沒有順序關係(面試題)
- package>import>class
- package : 只能有一個
- import:可以有多個
- class:可以有多個,建議是一個。
修飾符
- 許可權修飾符:
private
,預設的
,protected
,public
- 狀態修飾符:
static
,final
- 抽象修飾符:
abstract
許可權修飾符
類及其組成可以用的修飾符
類:
- 許可權修飾符:
預設的
,public
- 狀態修飾符(外部類):
final
, (內部類可以使用static
) - 抽象修飾符:
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
- public static
內部類
內部類概述
- 把類定義在其他類的內部,這個類就被稱為
內部類
。
- 舉例:在類A中定義了一個類B,類B就是內部類。
- 內部類的訪問特點:
- 內部類可以直接訪問外部類的成員,包括私有。
- 外部類要訪問內部類的成員,必須建立物件。
內部類的位置
- 按照內部類在類中定義的位置不同,可以分為如下兩種格式:
- 成員位置(成員內部類)
- 區域性位置(區域性內部類)
成員內部類
成員內部類不是靜態的:
外部類名.內部類名 物件名 = new 外部類物件.new 內部類物件;
- 一般加
private
為了保證資料的安全性
成員內部類是靜態的(被靜態修飾後的訪問方式是):
外部類名.內部類名 物件名 = new 外部類名.內部類名();
static
為了讓資料訪問更方便,一般加public
成員內部類不是靜態的例子
class Outer {
private int num = 10;
class Inner {
public void show() {
System.out.println(num);
}
}
}
class InnerClassDemo3 {
public static void main(String[] args) {
//格式:外部類名.內部類名 物件名 = new 外部類物件.new 內部類物件;
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
- 上面成員內部類的使用,在實際開發中是不會這樣使用的。因為一般內部類就是不讓外界直接訪問的。
class Body {
private class Heart {
public void operator() {
System.out.println("心臟搭橋");
}
}
public void method() {
if(如果你是外科醫生) {
Heart h = new Heart();
h.operator();
}
}
}
- 內部類被靜態修飾後的
方法
- 被靜態修飾的
成員內部類
只能訪問外部類
的靜態成員 - 格式:外部類名.內部類名 物件名 = new 外部類名.內部類名();
- 被靜態修飾的
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) {
//成員內部類被靜態修飾後的訪問方式是:
//格式:外部類名.內部類名 物件名 = new 外部類名.內部類名();
Outer.Inner oi = new Outer.Inner();
oi.show();
oi.show2();
//show2()的另一種呼叫方式
Outer.Inner.show2();
}
}
- 練習:補齊程式(注意:內部類和外部類沒有繼承關係)要求請填空分別輸出30 20 10
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
// Outer.this.num
}
}
}
區域性內部類
- 可以直接訪問
外部類
的成員 - 可以建立
內部類物件
,通過物件呼叫內部類方法
,來使用區域性內部類
功能 區域性內部類
訪問區域性變數
的注意事項:
- 必須被
final
修飾
- 因為區域性變數會隨著方法的呼叫完畢而消失,這個時候,區域性物件並沒有立馬從堆記憶體中消失,還要使用那個變數。為了讓資料還能繼續被使用,就用
fianl
修飾,這樣,在堆記憶體裡面儲存的其實是一個常量值。
- 因為區域性變數會隨著方法的呼叫完畢而消失,這個時候,區域性物件並沒有立馬從堆記憶體中消失,還要使用那個變數。為了讓資料還能繼續被使用,就用
- 必須被
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();
}
}
- 匿名內部類在開發中的使用
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("好好學習,天天向上");
}
});
}
}
- 匿名內部類面試題(重難點)
- 要求在控制檯輸出”HelloWorld”
interface Inter {
void show();
}
class Outer { //補齊程式碼
}
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
//分析:
/*
1:由Outer.method()可以看出method()應該是outer中的一個靜態方法。
2:Outer.method().show()可以看出method()方法的返回值是一個物件
3:由於介面Inter中有一個show()方法,所以認為method()方法的返回值型別是一個介面。
*/
//* 補充程式碼如下:在補齊程式碼後:
public static Inter method(){
return new Inter(){
public void show(){
System.out.println("HelloWorld");
}
}
}