13_Java面向物件_第13天(static、final、匿名物件、內部類、包、修飾符、程式碼塊)_講義
今日內容介紹
1、final 關鍵字
2、static 關鍵字
3、匿名物件
4、內部類
5、包的宣告與訪問
6、訪問修飾符
7、程式碼塊
第1章 final關鍵字
1.1 final的概念
繼承的出現提高了程式碼的複用性,並方便開發。但隨之也有問題,有些類在描述完之後,不想被繼承,或者有些類中的部分方法功能是固定的,不想讓子類重寫。可是當子類繼承了這些特殊類之後,就可以對其中的方法進行重寫,那怎麼解決呢?
要解決上述的這些問題,需要使用到一個關鍵字final,final的意思為最終,不可變。final是個修飾符,它可以用來修飾類,類的成員,以及區域性變數。
1.2 final的特點
final修飾類不可以被繼承,但是可以繼承其他類。
class Yy {}
final class Fu extends Yy{} //可以繼承Yy類
class Zi extends Fu{} //不能繼承Fu類
final修飾的方法不可以被覆蓋,但父類中沒有被final修飾方法,子類覆蓋後可以加final。
package cn.itcast.demo02; /* * 定義父類 * 一部分方法,寫出final修飾 * 子類可以繼承的,但是不能重寫 */ public class Fu { //父類的方法是final修飾,不可以被重寫 public final void show(){ System.out.println("fu類的最終方法"); } public void function(){ System.out.println("Fu類的一般方法"); } }
package cn.itcast.demo02;
public class Zi extends Fu {
//Cannot override the final method
//父類的方法是final修飾,不可以被重寫
//public void show(){}
public void function(){
System.out.println("Zi類的一般方法重寫");
}
}
package cn.itcast.demo02; /* * final修飾成員變數 * 成員變數,在堆記憶體中,具有預設值 * final修飾的成員變數,固定的不是記憶體的預設值 * 而他固定的是,成員變數的手動賦值,絕對不是記憶體的預設值 * * 成員變數的賦值,有兩種實現方式,一種是定義的時候,直接=賦值 這種方式最好,方便 * 另一種賦值方式,採用構造方法賦值 * 保證:被final修飾的成員變數,只能被賦值一次 * * 成員變數,需要在建立物件前賦值,否則報錯 * 構造方法,是建立物件中的事情,可以為成員變數賦值 * setXXX方法,建立物件之後的事情,不能為final修飾的成員賦值 */ public class Person { //The blank final field age may not have been initialized //final int age; //final int age = 0;//一種是定義的時候,直接=賦值 final int age;//採用構造方法賦值 public Person(int age) { //The final field Person.age cannot be assigned this.age = age; } //setXXX方法,建立物件之後的事情,不能為final修飾的成員賦值 // public void setAge(int age){ // this.age = age; // } }
package cn.itcast.demo02;
public class Test {
public static void main(String[] args) {
Zi z = new Zi();
z.function();
z.show();
final int i = 10;//被final修飾,一次賦值,終身不變
System.out.println(i);
//The final local variable i cannot be assigned.
//i = 11;
//final修飾引用變數問題
//變數,儲存的記憶體地址,終身不變
final Zi z2 = new Zi();
//z2記憶體地址不能在篡改
//z2 = new Zi();
//z2 = null;
z2.function();
}
}
class Fu {
// final修飾的方法,不可以被覆蓋,但可以繼承使用
public final void method1(){}
public void method2(){}
}
class Zi extends Fu {
//重寫method2方法
public final void method2(){}
}
final修飾的變數稱為常量,這些變數只能賦值一次。
final int i = 20;
i = 30; //賦值報錯,final修飾的變數只能賦值一次
引用型別的變數值為物件地址值,地址值不能更改,但是地址內的物件屬性值可以修改。
final Person p = new Person();
Person p2 = new Person();
p = p2; //final修飾的變數p,所記錄的地址值不能改變
p.name = "小明";//可以更改p物件中name屬性值
p不能為別的物件,而p物件中的name或age屬性值可更改。
修飾成員變數,需要在建立物件前賦值,否則報錯。(當沒有顯式賦值時,多個構造方法的均需要為其賦值。
class Demo {
//直接賦值
final int m = 100;
//final修飾的成員變數,需要在建立物件前賦值,否則報錯。
final int n;
public Demo(){
//可以在建立物件時所呼叫的構造方法中,為變數n賦值
n = 2016;
}
}
package cn.itcast.demo01;
/*
* 在類的定義上,加上修飾符,final
* 類:最終類,不能有子類,不可以被繼承
* 太監類
* String--就是哥太監類
* 但是使用方式,沒有變化,建立物件,呼叫方法
*/
public final class Fu {
public void show() {
System.out.println("final修飾類");
}
}
package cn.itcast.demo01;
//The type Zi cannot subclass the final class Fu
//public class Zi extends Fu{
//
//}
package cn.itcast.demo01;
public class Test {
public static void main(String[] args) {
Fu f = new Fu();
f.show();
}
}
第2章 static關鍵字
2.1 static概念
當在定義類的時候,類中都會有相應的屬性和方法。而屬性和方法都是通過建立本類物件呼叫的。當在呼叫物件的某個方法時,這個方法沒有訪問到物件的特有資料時,方法建立這個物件有些多餘。可是不建立物件,方法又調用不了,這時就會想,那麼我們能不能不建立物件,就可以呼叫方法呢?
可以的,我們可以通過static關鍵字來實現。static它是靜態修飾符,一般用來修飾類中的成員。
2.2 static特點
被static修飾的成員變數屬於類,不屬於這個類的某個物件。(也就是說,多個物件在訪問或修改static修飾的成員變數時,其中一個物件將static成員變數值進行了修改,其他物件中的static成員變數值跟著改變,即多個物件共享同一個static成員變數)
程式碼演示:
class Demo {
public static int num = 100;
}
class Test {
public static void main(String[] args) {
Demo d1 = new Demo();
Demo d2 = new Demo();
d1.num = 200;
System.out.println(d1.num); //結果為200
System.out.println(d2.num); //結果為200
}
}
被static修飾的成員可以並且建議通過類名直接訪問。
訪問靜態成員的格式:
類名.靜態成員變數名
類名.靜態成員方法名(引數)
物件名.靜態成員變數名 ------不建議使用該方式,會出現警告
物件名.靜態成員方法名(引數) ------不建議使用該方式,會出現警告
程式碼演示:
class Demo {
//靜態成員變數
public static int num = 100;
//靜態方法
public static void method(){
System.out.println("靜態方法");
}
}
class Test {
public static void main(String[] args) {
System.out.println(Demo.num);
Demo.method();
}
}
2.3 static注意事項
靜態內容是優先於物件存在,只能訪問靜態,不能使用this/super。靜態修飾的內容存於靜態區。
package cn.itcast.demo04;
public class Fu {
static int a = 1;
public static void show(){
System.out.println("父類的靜態成員方法");
}
}
package cn.itcast.demo04;
public class Zi extends Fu {
//static int a = 2;
public static void show(){
System.out.println("子類的靜態成員方法");
}
}
package cn.itcast.demo04;
/*
* 多型呼叫中,編譯看誰,執行看誰
* 編譯都看 = 左邊的父類,父類有編譯成功,父類沒有之間編譯失敗
* 執行,靜態方法,執行父類中的靜態方法
* 執行,非靜態方法,執行子類的重寫方法
* (多型的魅力:當變數名指向不同的子類物件時,由於每個子類重寫父類方法的內容不同,所以會呼叫不同的方法。)
* 執行,成員變數,編譯執行全是父類
*
*/
public class Test {
//Math按F3可檢視到
public static final double PI = 3.14159265358979323846;
public static void main(String[] args) {
Fu f = new Zi();
//成員變數編譯看父類
System.out.println(f.a);//1
//呼叫還是父類的靜態方法,原因是:靜態屬於類,不屬於物件
//物件的多型性,靜態和物件無關,父類的引用,靜態方法
f.show();
System.out.println(Test.PI);
}
}
class Demo {
//成員變數
public int num = 100;
//靜態方法
public static void method(){
//this.num; 不能使用this/super。
System.out.println(this.num);
}
}
同一個類中,靜態成員只能訪問靜態成員
class Demo {
//成員變數
public int num = 100;
//靜態成員變數
public static int count = 200;
//靜態方法
public static void method(){
//System.out.println(num); 靜態方法中,只能訪問靜態成員變數或靜態成員方法
System.out.println(count);
}
}
main方法為靜態方法僅僅為程式執行入口,它不屬於任何一個物件,可以定義在任意類中。
2.4 定義靜態常量
開發中,我們想在類中定義一個靜態常量,通常使用public static final修飾的變數來完成定義。此時變數名用全部大寫,多個單詞使用下劃線連線。
定義格式:
public static final 資料型別 變數名 = 值;
如下演示:
class Company {
public static final String COMPANY_NAME = "傳智播客";
public static void method(){
System.out.println("一個靜態方法");
}
}
當我們想使用類的靜態成員時,不需要建立物件,直接使用類名來訪問即可。
System.out.println(Company.COMPANY_NAME); //列印傳智播客
Company.method(); // 呼叫一個靜態方法
注意:
介面中的每個成員變數都預設使用public static final修飾。
所有介面中的成員變數已是靜態常量,由於介面沒有構造方法,所以必須顯示賦值。可以直接用介面名訪問。
interface Inter {
public static final int COUNT = 100;
}
訪問介面中的靜態變數
Inter.COUNT
package cn.itcast.demo03;
/*
* 定義Person類
* 定義物件的特有資料,和物件的共享資料
* 物件的特有資料(非靜態修飾) 呼叫者只能是new物件
* 物件的共享資料(靜態修飾) 呼叫者能是new物件,還能是類名字呼叫
*
* 被靜態修飾的成員,可以被類名字直接呼叫
*/
public class Person {
String name;
static String className;
}
package cn.itcast.demo03;
/*
* 靜態的注意事項
*
* 在靜態中不能呼叫非靜態
* 為什麼呢?為什麼靜態不能呼叫非靜態,生命週期
* 靜態優先於非靜態存在於記憶體中
*
* 靜態前人,先人,非靜態後人
* 靜態不能寫this,不能寫super(靜態優先於物件,他是沒有物件的,哪有本類或者父類之說)
*
* 問題:
* static 修飾到底什麼時候使用,應用場景
* static修飾成員變數,成員方法
* 成員變數加static,根據具體的事物,具體分析問題
* 定義事物的時候,多個事物之間是否有共性的資料
* 請你將共性的資料定義為靜態成員變數
* 成員方法加static,跟著變數走
* 如果方法,沒有呼叫過非靜態成員變數,將方法定義為靜態
*/
public class Student {
//生命週期一樣
private static String name;
private static int age;
private char sex;
public void show1(){
System.out.println(sex);
}
//這個方法沒有用到非靜態成員變數,也沒有需要new一下,也不需要在堆記憶體中,方法就加靜態,
public int getSum(int a,int b,int c){
return a + b + c;
}
public static void function(){
System.out.println(name + age);
}
//非靜態能呼叫靜態 後人呼叫前人
public void show(){
System.out.println(name + age);
}
public static void main(String[] args) {
//method();
Student s = new Student();
s.method();
}
public void method(){
}
}
package cn.itcast.demo03;
public class Test {
public static void main(String[] args) {
System.out.println(Person.className);
Person p1 = new Person();
Person p2 = new Person();
p1.name = "哈哈";
p2.name = "嘻嘻";
System.out.println(p1.name);
System.out.println(p2.name);
//物件呼叫類的靜態成員變數
p1.className = "基礎班";
System.out.println(p2.className);//不建議使用該方式,會出現警告
System.out.println(p1.className);//不建議使用該方式,會出現警告
System.out.println(Person.className);
}
}
第3章 匿名物件
3.1 匿名物件的概念
匿名物件是指建立物件時,只有建立物件的語句,卻沒有把物件地址值賦值給某個變數。
如:已經存在的類:
public class Person{
public void eat(){
System.out.println();
}
}
建立一個普通物件
Person p = new Person();
建立一個匿名物件
new Person();
3.2 匿名物件的特點
建立匿名物件直接使用,沒有變數名。
new Person().eat() //eat方法被一個沒有名字的Person物件呼叫了。
匿名物件在沒有指定其引用變數時,只能使用一次。
new Person().eat(); 建立一個匿名物件,呼叫eat方法
new Person().eat(); 想再次呼叫eat方法,重新建立了一個匿名物件
匿名物件可以作為方法接收的引數、方法返回值使用
class Demo {
public static Person getPerson(){
//普通方式
//Person p = new Person();
//return p;
//匿名物件作為方法返回值
return new Person();
}
public static void method(Person p){}
}
class Test {
public static void main(String[] args) {
//呼叫getPerson方法,得到一個Person物件
Person person = Demo.getPerson();
//呼叫method方法
Demo.method(person);
//匿名物件作為方法接收的引數
Demo.method(new Person());
}
}
package cn.itcast.demo05;
public class Person {
public void eat(){
System.out.println("人在吃");
}
}
package cn.itcast.demo05;
//import java.util.Scanner;
/*
* 有名字的物件,引用型別變數,可以反覆使用
* 匿名物件,沒有引用變數,只能使用一次
*
* 匿名物件可以當作引數傳遞
* 匿名物件可以做方法的返回值
*/
public class Test {
public static void main(String[] args) {
Person p = new Person();
p.eat();
System.out.println("匿名物件,沒有引用變數,只能使用一次");
new Person().eat();
//在這麼呼叫,已經是一個新的人
new Person().eat();
//Ctrl + 1幫助改錯
// int number = new Scanner(System.in).nextInt();
// Scanner sc = new Scanner(System.in);
// sc.next();
// sc.nextInt();
//匿名物件做方法引數傳遞
System.out.println("匿名物件做方法引數傳遞");
method(new Person());
method(p);
//匿名物件可以做方法的返回值
System.out.println("匿名物件可以做方法的返回值");
Person p3 = method();
p3.eat();
}
/*
* 呼叫方法method,傳遞Person型別物件
*/
public static void method(Person p){
p.eat();
}
//方法返回值是Person型別
//方法return語句,返回的是這個類的物件
public static Person method(){
//Person p = new Person();
return new Person();
}
}
第4章 內部類
4.1 內部類概念
package cn.itcast.demo06;
/*
* 內部類的定義
* 將內部類,定義在了外部的成員變數
* 類名Outer,內部類名Inner
*
* 成員內部類,可以使用成員修飾符,public static...
* 也是個類,可以繼承,可以實現介面
*
* 呼叫規則:內部類,可以使用外部類成員,包含私有
* 外部類要使用內部類的成員,必須建立內部類物件
*/
public class Outer {
private int a = 1;
//外部類成員位置,定義內部類
class Inner{
public void Inner(){
System.out.println("內部類方法Inner " + a);
}
}
}
package cn.itcast.demo06;
public class Test {
public static void main(String[] args) {
/*
* 呼叫外部類中的內部類的方法Inner()
* 依靠外部類物件,找到內部類,通過內部類物件,呼叫內部類的方法
* 格式:
* 外部類名.內部類名 變數 = new 外部類名().new 內部類名()
* 變數.內部類方法()
*/
Outer.Inner in = new Outer().new Inner();
in.Inner();
}
}
什麼是內部類
將類寫在其他類的內部,可以寫在其他類的成員位置和區域性位置,這時寫在其他類內部的類就稱為內部類。其他類也稱為外部類。
什麼時候使用內部類
在描述事物時,若一個事物內部還包含其他可能包含的事物,比如在描述汽車時,汽車中還包含這發動機,這時發動機就可以使用內部類來描述。
class 汽車 { //外部類
class 發動機 { //內部類
}
}
內部類的分類
內部類分為成員內部類與區域性內部類。
我們定義內部類時,就是一個正常定義類的過程,同樣包含各種修飾符、繼承與實現關係等。在內部類中可以直接訪問外部類的所有成員。
4.2 成員內部類
package cn.itcast.demo07;
public class Outer {
int i = 1;
class Inner{
int i = 2;
public void Inner(){
int i = 3;
System.out.println("i: " + i);
System.out.println("this.i: " + this.i);
System.out.println("Outer.this.i: " + Outer.this.i);
}
}
}
package cn.itcast.demo07;
public class Test {
public static void main(String[] args) {
/*
* 呼叫外部類中的內部類的方法Inner()
* 依靠外部類物件,找到內部類,通過內部類物件,呼叫內部類的方法
* 格式:
* 外部類名.內部類名 變數 = new 外部類名().new 內部類名()
* 變數.內部類方法()
*/
Outer.Inner in = new Outer().new Inner();
in.Inner();//3
}
}
成員內部類,定義在外部類中的成員位置。與類中的成員變數相似,可通過外部類物件進行訪問
定義格式
class 外部類 {
修飾符 class 內部類 {
//其他程式碼
}
}
訪問方式
外部類名.內部類名 變數名 = new 外部類名().new 內部類名();
成員內部類程式碼演示
定義類
class Body {//外部類,身體
private boolean life= true; //生命狀態
public class Heart { //內部類,心臟
public void jump() {
System.out.println("心臟噗通噗通的跳")
System.out.println("生命狀態" + life); //訪問外部類成員變數
}
}
}
訪問內部類
public static void main(String[] args) {
//建立內部類物件
Body.Heart bh = new Body().new Heart();
//呼叫內部類中的方法
bh.jump();
}
4.3 區域性內部類
package cn.itcast.demo08;
/*
* 區域性內部類
* 將一個類,定義在方法中
*/
public class Outer {
public void out(){
//int x = 1想拿到這個x,就得這個方法返回值為int,然後返回出來x
class Inner{
public void Inner(){
System.out.println("區域性內部類方法");
}
}
//建立內部類物件,呼叫Inner方法
Inner in = new Inner();
in.Inner();
}
}
package cn.itcast.demo08;
public class Test {
public static void main(String[] args) {
//呼叫區域性內部類的方法Inner()
new Outer().out();
}
}
區域性內部類,定義在外部類方法中的區域性位置。與訪問方法中的區域性變數相似,可通過呼叫方法進行訪問
定義格式
class 外部類 {
修飾符 返回值型別 方法名(引數) {
class 內部類 {
//其他程式碼
}
}
}
訪問方式
在外部類方法中,建立內部類物件,進行訪問
區域性內部類程式碼演示
定義類
class Party {//外部類,聚會
public void puffBall(){// 吹氣球方法
class Ball {// 內部類,氣球
public void puff(){
System.out.println("氣球膨脹了");
}
}
//建立內部類物件,呼叫puff方法
new Ball().puff();
}
}
訪問內部類
public static void main(String[] args) {
//建立外部類物件
Party p = new Party();
//呼叫外部類中的puffBall方法
p.puffBall();
}
4.4 內部類的實際使用——匿名內部類
package cn.itcast.demo09;
public interface Smoking {
public abstract void smoking();
}
/*
* 實現類,實現介面 重寫介面抽象方法,建立實現類物件
* class XXX implements Smoking{
* public void smoking(){
*
* }
*}
* 一般方法呼叫:
* XXX x = new XXX();
* x.smoking();
* 多型
* Smoking s = new XXX();
* s.smoking();
*
*匿名內部類,簡化問題:定義實現類,重寫方法,建立實現類物件,合為一步實現
*/
package cn.itcast.demo09;
public class Test {
public static void main(String[] args) {
/*
* 匿名內部類
* 定義實現類,重寫方法,建立實現類物件,一步搞定
* 格式:
* new 介面或者父類(){
* 重寫抽象方法
* };
* 從new開始,到分號結束
*/
new Smoking(){
public void smoking(){
System.out.println("人在吸菸");
}
}.smoking();
}
}
4.4.1 匿名內部類概念
內部類是為了應對更為複雜的類間關係。檢視原始碼中會涉及到,而在日常業務中很難遇到,這裡不做贅述。
最常用到的內部類就是匿名內部類,它是區域性內部類的一種。
定義的匿名內部類有兩個含義:
臨時定義某一指定型別的子類
定義後即刻建立剛剛定義的這個子類的物件
4.4.2 定義匿名內部類的作用與格式
package cn.itcast.demo09;
public abstract class Animal {
public abstract void eat();
public abstract void sleep();
}
package cn.itcast.demo09;
/*
* new Animal(){
public void eat(){
System.out.println("在吃飯");
}
public void sleep(){
System.out.println("在睡覺");
}
};
* 以上程式碼,就是Animal的子類的物件
* 多型性,父類引用 = 子類的物件
* cn.itcast.demo09.Test2
*/
public class Test2 {
public static void main(String[] args) {
//多型性,父類引用 = 子類的物件
Animal a = new Animal(){
public void eat(){
System.out.println("在吃飯");
}
public void sleep(){
System.out.println("在睡覺");
}
};
a.eat();
a.sleep();
}
}
作用:匿名內部類是建立某個型別子類物件的快捷方式。
格式:
new 父類或介面(){
//進行方法重寫
};
程式碼演示
//已經存在的父類:
public abstract class Person{
public abstract void eat();
}
//定義並建立該父類的子類物件,並用多型的方式賦值給父類引用變數
Person p = new Person(){
public void eat() {
System.out.println(“我吃了”);
}
};
//呼叫eat方法
p.eat();
使用匿名物件的方式,將定義子類與建立子類物件兩個步驟由一個格式一次完成,。雖然是兩個步驟,但是兩個步驟是連在一起完成的。
匿名內部類如果不定義變數引用,則也是匿名物件。程式碼如下:
new Person(){
public void eat() {
System.out.println(“我吃了”);
}
}.eat();
第5章 包的宣告與訪問
5.1 包的概念
java的包,其實就是我們電腦系統中的資料夾,包裡存放的是類檔案。
當類檔案很多的時候,通常我們會採用多個包進行存放管理他們,這種方式稱為分包管理。
在專案中,我們將相同功能的類放到一個包中,方便管理。並且日常專案的分工也是以包作為邊界。
類中宣告的包必須與實際class檔案所在的資料夾情況相一致,即類宣告在a包下,則生成的.class檔案必須在a資料夾下,否則,程式執行時會找不到類。
5.2 包的宣告格式
通常使用公司網址反寫,可以有多層包,包名採用全部小寫字母,多層包之間用”.”連線
類中包的宣告格式:
package 包名.包名.包名…;
如:黑馬程式設計師網址itheima.com那麼網址反寫就為com.itheima
傳智播客 itcast.cn 那麼網址反寫就為 cn.itcast
注意:宣告包的語句,必須寫在程式有效程式碼的第一行(註釋不算)
程式碼演示:
package cn.itcast; //包的宣告,必須在有效程式碼的第一行
import java.util.Scanner;
import java.util.Random;
public class Demo {}
5.3 包的訪問
在訪問類時,為了能夠找到該類,必須使用含有包名的類全名(包名.類名)。
包名.包名….類名
如: java.util.Scanner
java.util.Random
cn.itcast.Demo
帶有包的類,建立物件格式:包名.類名 變數名 = new包名.類名();
cn.itcast.Demo d = new cn.itcast.Demo();
前提:包的訪問與訪問許可權密切相關,這裡以一般情況來說,即類用public修飾的情況。
類的簡化訪問
當我們要使用一個類時,這個類與當前程式在同一個包中(即同一個資料夾中),或者這個類是java.lang包中的類時通常可以省略掉包名,直接使用該類。
如:cn.itcast包中有兩個類,PersonTest類,與Person類。我們在PersonTest類中,訪問Person類時,由於是同一個包下,訪問時可以省略包名,即直接通過類名訪問 Person。
類名 變數名 = new類名();
Person p = new Person();
當我們要使用的類,與當前程式不在同一個包中(即不同資料夾中),要訪問的類必須用public修飾才可訪問。
package cn.itcst02;
public class Person {}
5.4 import導包
我們每次使用類時,都需要寫很長的包名。很麻煩,我們可以通過import導包的方式來簡化。
可以通過導包的方式使用該類,可以避免使用全類名編寫(即,包類.類名)。
導包的格式:
import 包名.類名;
當程式匯入指定的包後,使用類時,就可以簡化了。演示如下
//匯入包前的方式
//建立物件
java.util.Random r1 = new java.util.Random();
java.util.Random r2 = new java.util.Random();
java.util.Scanner sc1 = new java.util.Scanner(System.in);
java.util.Scanner sc2 = new java.util.Scanner(System.in);
//匯入包後的方式
import java.util.Random;
import java.util.Scanner;
//建立物件
Random r1 = new Random();
Random r2 = new Random();
Scanner sc1 = new Scanner(System.in);
Scanner sc2 = new Scanner(System.in);
import導包程式碼書寫的位置:在宣告包package後,定義所有類class前,使用導包import包名.包名.類名;
第6章 訪問修飾符
在Java中提供了四種訪問許可權,使用不同的訪問許可權時,被修飾的內容會有不同的訪問許可權,以下表來說明不同許可權的訪問能力:
歸納一下:在日常開發過程中,編寫的類、方法、成員變數的訪問
要想僅能在本類中訪問使用private修飾;
要想本包中的類都可以訪問不加修飾符即可;default
要想本包中的類與其他包中的子類可以訪問使用protected修飾
要想所有包中的所有類都可以訪問使用public修飾。
注意:如果類用public修飾,則類名必須與檔名相同。一個檔案中只能有一個public修飾的類。
package cn.itcast.demo10;
public class A {
int i = 1;//default許可權
//要想本包中的類與其他包中的子類可以訪問使用protected修飾
//受保護許可權,許可權只給子類
protected void abc(){
System.out.println("abc");
}
}
package cn.itcast.demo10;
public class B{
public void show() {
//default許可權能在本包和自己能用,子類都不行
//new A().i
}
}
package cn.itcast.demo11;
import cn.itcast.demo10.*;
public class C extends A{
public void show(){
//System.out.println(i);//預設許可權default只能在本包使用
//new A().abc()沒有
//受保護許可權,只能是子類的裡面,呼叫父類的受保護成員
//super
abc();
}
}
package cn.itcast.demo11;
public class Test {
public static void main(String[] args) {
C c = new C();
//c.abc();c.沒有abc()方法,說明受保護許可權不能呼叫
}
}
第7章 程式碼塊
7.1 區域性程式碼塊
區域性程式碼塊是定義在方法或語句中
特點:
以”{}”劃定的程式碼區域,此時只需要關注作用域的不同即可
方法和類都是以程式碼塊的方式劃定邊界的
class Demo{
public static void main(String[] args) {
{
int x = 1;
System.out.println("普通程式碼塊" + x);
}
int x = 99;
System.out.println("程式碼塊之外" + x);
}
}
結果:
普通程式碼塊1
程式碼塊之外99
7.2 構造程式碼塊
構造程式碼塊是定義在類中成員位置的程式碼塊
特點:
優先於構造方法執行,構造程式碼塊用於執行所有物件均需要的初始化動作
每建立一個物件均會執行一次構造程式碼塊。
public class Person {
private String name;
private int age;
//構造程式碼塊
{
System.out.println("構造程式碼塊執行了");
}
Person(){
System.out.println("Person無引數的建構函式執行");
}
Person(int age){
this.age = age;
System.out.println("Person(age)引數的建構函式執行");
}
}
class PersonDemo{
public static void main(String[] args) {
Person p = new Person();
Person p1 = new Person(23);
}
}
7.3 靜態程式碼塊
靜態程式碼塊是定義在成員位置,使用static修飾的程式碼塊。
特點:
它優先於主方法執行、優先於構造程式碼塊執行,當以任意形式第一次使用到該類時執行。
該類不管建立多少物件,靜態程式碼塊只執行一次。
可用於給靜態變數賦值,用來給類進行初始化。
public class Person {
private String name;
private int age;
//靜態程式碼塊
static{
System.out.println("靜態程式碼塊執行了");
}
}
package cn.itcast.demo12;
/*
* 靜態程式碼塊,只執行一次
* 構造程式碼塊,new一次,就執行一次,優先於構造方法
* 構造方法,new一次,就執行一次
*/
public class Person {
private String name;
private int age;
public Person(String name,int age){
this.age = age;
this.name = name;
System.out.println("我是有參建構函式");
}
//構造程式碼塊
{
System.out.println("構造程式碼塊");
}
//靜態程式碼塊
static{
System.out.println("靜態程式碼塊");
}
}
package cn.itcast.demo12;
public class Test {
public static void main(String[] args) {
//限定生命週期和作用域
{
int a = 1;
System.out.println(a);
}
//被限定了作用域和生命週期,已經沒有a
//System.out.println(a);//a cannot be resolved to a variable
Person p = new Person("張三",20);
Person p1 = new Person("張三1",210);
}
}
第8章 總結
8.1 知識點總結
final:關鍵字,最終的意思
final修飾的類:最終的類,不能被繼承
final修飾的變數: 相當於是一個常量, 在編譯生產.class檔案後,該變數變為常量值
final修飾的方法: 最終的方法,子類不能重寫,可以繼承過來使用
static : 關鍵字, 靜態的意思
可以用來修飾類中的成員(成員變數,成員方法)
注意: 也可以用來修飾成員內部類
特點:
被靜態所修飾的成員,會被所有的物件所共享
被靜態所修飾的成員,可以通過類名直接呼叫,方便
Person.country = “中國”;
Person.method();
注意事項:
靜態的成員,隨著類的載入而載入,優先於物件存在
在靜態方法中,沒有this關鍵字
靜態方法中,只能呼叫靜態的成員(靜態成員變數,靜態成員方法
匿名物件:一個沒有名字的物件
特點:
建立匿名物件直接使用,沒有變數名
匿名物件在沒有指定其引用變數時,只能使用一次
匿名物件可以作為方法接收的引數、方法返回值使用
內部類:在一個類中,定義了一個新類,這個新的類就是內部類
class A {//外部類
class B{// 內部類
}
}
特點:
內部類可以直接訪問外部類的成員,包含私有的成員
包的宣告與訪問
類中包的宣告格式:
package 包名.包名.包名…;
帶有包的類,建立物件格式:包名.類名 變數名 = new包名.類名();
cn.itcast.Demo d = new cn.itcast.Demo();
導包的格式:
import 包名.類名;
許可權修飾符
public : 公共的
protected: 受保護的
private : 私有的
public protected 預設的 private
在當前類中 Y Y Y Y
同一包中的其他類 Y Y Y
不同包中的子類 Y Y
不同包中的其他類 Y
程式碼塊:
區域性程式碼塊:定義在方法中的,用來限制變數的作用範圍
構造程式碼塊:定義在類中方法外,用來給物件中的成員初始化賦值
靜態程式碼塊:定義在類中方法外,用來給類的靜態成員初始化賦值