今日内容介紹
1、final 關鍵字
2、static 關鍵字
3、匿名對象
4、内部類
5、包的聲明與通路
6、通路修飾符
7、代碼塊
第一節課
01(面向對象)final關鍵字概念.avi 02:20
02(面向對象)final修飾類.avi 04:25
03(面向對象)final修飾方法.avi 04:01
04(面向對象)final修飾局部變量.avi 05:57
05(面向對象)final修飾成員變量.avi 10:04
06(面向對象)static的概念.avi 09:28
第二節課
07(面向對象)static修飾的對象特有資料.avi 06:53
08(面向對象)static的記憶體圖.avi 14:09
09(面向對象)static注意事項_靜态不能直接調用非靜态.avi 08:02
10(面向對象)static靜态的使用場景.avi 08:14
11(面向對象)對象中的靜态調用.avi 06:45
12(面向對象)定義靜态常量.avi 03:44
第三節課
13(面向對象)匿名對象.avi 12:46
14(面向對象)内部類.avi 03:34
15(面向對象)成員内部類的調用格式.avi 09:19
16(面向對象)成員内部類的同名變量調用.avi 02:59
17(面向對象)局部内部類.avi 07:18
18(面向對象)匿名内部類.avi 12:22
第四節課
19(面向對象)匿名内部類_2.avi 04:19
20(面向對象)包的概念.avi 02:29
21(面向對象)導入包.avi 06:48
22(面向對象)權限修飾符.avi 12:47
23(面向對象)代碼塊.avi 05:17
============上面的内容,友善我們隻做ppt,word教案以及書寫下面的簡要的筆記=================
=======================第一節課開始=============================================
01final關鍵字概念
* A: 概述
繼承的出現提高了代碼的複用性,并友善開發。但随之也有問題,有些類在描述完之後,不想被繼承,
或者有些類中的部分方法功能是固定的,不想讓子類重寫。可是當子類繼承了這些特殊類之後,
就可以對其中的方法進行重寫,那怎麼解決呢?
要解決上述的這些問題,需要使用到一個關鍵字final,final的意思為最終,不可變。
final是個修飾符,它可以用來修飾類,類的成員,以及局部變量。
02final修飾類義
* A: final 修飾類
final修飾類不可以被繼承,但是可以繼承其他類。
* B: 案例
class Yy {}
final class Fu extends Yy{} //可以繼承Yy類
class Zi extends Fu{} //不能繼承Fu類
03final修飾方法
* A: final修飾方法
final修飾的方法不可以被覆寫,但父類中沒有被final修飾方法,子類覆寫後可以加final。
* B: 案例
class Fu {
// final修飾的方法,不可以被覆寫,但可以繼承使用
public final void method1(){}
public void method2(){}
}
class Zi extends Fu {
//重寫method2方法
public final void method2(){}
}
04final修飾局部變量
* A:修飾基本資料類型變量
final修飾的變量稱為常量,這些變量隻能指派一次
* B:案例1
final int i = 20;
i = 30; //指派報錯,final修飾的變量隻能指派一次
* C: 修飾引用資料類型
引用類型的變量值為對象位址值,位址值不能更改,但是位址内的對象屬性值可以修改
* D: 修飾引用資料類型
final Person p = new Person();
Person p2 = new Person();
p = p2; //final修飾的變量p,所記錄的位址值不能改變
p.name = "小明";//可以更改p對象中name屬性值
p不能為别的對象,而p對象中的name或age屬性值可更改。
05final修飾成員變量
* A: 修飾成員變量
修飾成員變量,需要在建立對象前指派,否則報錯。(當沒有顯式指派時,多個構造方法的均需要為其指派。)
* B: 案例
class Demo {
//直接指派
final int m = 100;
//final修飾的成員變量,需要在建立對象前指派,否則報錯。
final int n;
public Demo(){
//可以在建立對象時所調用的構造方法中,為變量n指派
n = 2016;
}
}
06static的概念
* A:概念
當在定義類的時候,類中都會有相應的屬性和方法。而屬性和方法都是通過建立本類對象調用的。
當在調用對象的某個方法時,這個方法沒有通路到對象的特有資料時,方法建立這個對象有些多餘。
可是不建立對象,方法又調用不了,這時就會想,那麼我們能不能不建立對象,就可以調用方法呢?
可以的,我們可以通過static關鍵字來實作。static它是靜态修飾符,一般用來修飾類中的成員。
==============================第二節課開始====================================
07static修飾的對象特有資料
* A:特點1:
被static修飾的成員變量屬于類,不屬于這個類的某個對象。
(也就是說,多個對象在通路或修改static修飾的成員變量時,其中一個對象将static成員變量值進行了修改,
其他對象中的static成員變量值跟着改變,即多個對象共享同一個static成員變量)
* B: 代碼示範
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
}
}
08static的記憶體圖
* A: 略
參考day13_source 靜态的記憶體圖.jpg
09static注意事項_靜态不能直接調用非靜态
* A: 注意事項
被static修飾的成員可以并且建議通過類名直接通路。
* B: 通路靜态成員的格式:
類名.靜态成員變量名
類名.靜态成員方法名(參數)
對象名.靜态成員變量名 ------不建議使用該方式,會出現警告
對象名.靜态成員方法名(參數) ------不建議使用該方式,會出現警告
* C: 代碼示範
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();
}
}
10static靜态的使用場景
* A: 使用場景
static可以修飾成員變量和成員方法。
什麼時候使用static修飾成員變量?
加static修飾成員的時候,這個成員會被類的所有對象所共享。一般我們把共性資料定義為靜态的變量
什麼時候使用static修飾成員方法?
靜态的方法隻能通路靜态的成員,如果靜态方法中引用到了靜态的其他成員,那麼這個方法需要聲明為靜态的方法。
11對象中的靜态調用
* A: 對象的靜态調用
在多态中,非靜态編譯看父類,運作看子類,父類沒有編譯失敗。
但多态中的靜态方法,編譯看父類,運作仍然看父類。因為靜态和對象沒有關系,屬于靜态綁定。
* B: 舉例
public class Test{
public static void main(String[] args){
Fu f = new Zi();
f.show(); //父類的引用和父類的方法綁定,和對象無關,不會在運作時動态的執行子類特有的方法。
}
}
12定義靜态常量
* A: 靜态常量
開發中,我們想在類中定義一個靜态常量,通常使用public static final修飾的變量來完成定義。
此時變量名用全部大寫,多個單詞使用下劃線連接配接。
* B: 定義格式:
public static final 資料類型 變量名 = 值;
* C: 如下示範:
class Company {
public static final String COMPANY_NAME = "傳智播客";
public static void method(){
System.out.println("一個靜态方法");
}
}
當我們想使用類的靜态成員時,不需要建立對象,直接使用類名來通路即可。
System.out.println(Company.COMPANY_NAME); //列印傳智播客
Company.method(); // 調用一個靜态方法
* D: 注意:
接口中的每個成員變量都預設使用public static final修飾。
所有接口中的成員變量已是靜态常量,由于接口沒有構造方法,是以必須顯示指派。可以直接用接口名通路。
interface Inter {
public static final int COUNT = 100;
}
通路接口中的靜态變量
Inter.COUNT
==============================第三節課開始====================================
13匿名對象
* A:匿名對象的概述
* 匿名對象是指建立對象時,隻有建立對象的語句,卻沒有把對象位址值指派給某個變量。
* B:案例
public class Person{
public void eat(){
System.out.println();
}
}
建立一個普通對象
Person p = new Person();
建立一個匿名對象
new Person();
* C: 匿名對象的特點
a:建立匿名對象直接使用,沒有變量名。
new Person().eat() //eat方法被一個沒有名字的Person對象調用了。
b:匿名對象在沒有指定其引用變量時,隻能使用一次。
new Person().eat(); 建立一個匿名對象,調用eat方法
new Person().eat(); 想再次調用eat方法,重新建立了一個匿名對象
c:匿名對象可以作為方法接收的參數、方法傳回值使用
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());
}
}
14内部類
* A: 内部類的概述
将類寫在其他類的内部,可以寫在其他類的成員位置和局部位置,這時寫在其他類内部的類就稱為内部類。
其他類也稱為外部類。
* B: 什麼時候使用内部類
在描述事物時,若一個事物内部還包含其他可能包含的事物,比如在描述汽車時,汽車中還包含這發動機,
這時發動機就可以使用内部類來描述。
class 汽車 { //外部類
class 發動機 { //内部類
}
}
* C: 内部類的分類
内部類分為成員内部類與局部内部類。
我們定義内部類時,就是一個正常定義類的過程,同樣包含各種修飾符、繼承與實作關系等。
在内部類中可以直接通路外部類的所有成員。
15成員内部類的調用格式
* A: 格式
成員内部類,定義在外部類中的成員位置。與類中的成員變量相似,可通過外部類對象進行通路
* B: 定義格式
class 外部類 {
修飾符 class 内部類 {
//其他代碼
}
}
* C: 通路方式
外部類名.内部類名 變量名 = new 外部類名().new 内部類名();
* D: 成員内部類代碼示範
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();
}
16成員内部類的同名變量調用
* A: 代碼實作
public class Outer {
int i = 1;
class Inner {
int i = 2;
public void inner(){
int i = 3;
System.out.println(Outer.this.i);
}
}
}
17局部内部類
* A 局部内部類,定義在外部類方法中的局部位置。與通路方法中的局部變量相似,可通過調用方法進行通路.
* B 定義格式
class 外部類 {
修飾符 傳回值類型 方法名(參數) {
class 内部類 {
//其他代碼
}
}
}
* C 通路方式
在外部類方法中,建立内部類對象,進行通路
* D 局部内部類代碼示範
定義類
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();
}
==============================第四節課開始====================================
18匿名内部類
* A: 概述
内部類是為了應對更為複雜的類間關系。檢視源代碼中會涉及到,而在日常業務中很難遇到,這裡不做贅述。
最常用到的内部類就是匿名内部類,它是局部内部類的一種。
定義的匿名内部類有兩個含義:
臨時定義某一指定類型的子類
定義後即刻建立剛剛定義的這個子類的對象
* B: 本質
匿名内部類的本質是一個實作了接口或繼承了某個類的子類匿名對象.
* C: 案例
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();
*
* 匿名内部類,簡化問題: 定義實作類,重寫方法,建立實作類對象,合為一步完成
*/
測試類:
public class Test {
public static void main(String[] args) {
//使用匿名内部類
/*
* 定義實作類,重寫方法,建立實作類對象,一步搞定
* 格式:
* new 接口或者父類(){
* 重寫抽象方法
* };
* 從 new開始,到分号結束
* 建立了接口的實作類的對象
*/
new Smoking(){
public void smoking(){
System.out.println("人在吸煙");
}
}.smoking();
}
}
19匿名内部類_2
* A: 匿名内部類案例示範
public abstract class Animal {
public abstract void eat();
public abstract void sleep();
}
測試代碼
/*
* new Animal(){
public void eat(){
System.out.println("在吃飯");
}
public void sleep(){
System.out.println("在睡覺");
}
};
以上代碼,就是Animal的子類的對象
多态性, 父類引用 = 子類的對象
*/
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();
}
}
20包的概念
* A: 概念
java的包,其實就是我們電腦系統中的檔案夾,包裡存放的是類檔案。
當類檔案很多的時候,通常我們會采用多個包進行存放管理他們,這種方式稱為分包管理。
在項目中,我們将相同功能的類放到一個包中,友善管理。并且日常項目的分工也是以包作為邊界。
類中聲明的包必須與實際class檔案所在的檔案夾情況相一緻,即類聲明在a包下,則生成的.class檔案必須在a檔案夾下,否則,程式運作時會找不到類。
* B 聲明格式
通常使用公司網址反寫,可以有多層包,包名采用全部小寫字母,多層包之間用”.”連接配接
類中包的聲明格式:
package 包名.包名.包名…;
如:黑馬程式員網址itheima.com那麼網址反寫就為com.itheima
傳智播客 itcast.cn 那麼網址反寫就為 cn.itcast
注意:聲明包的語句,必須寫在程式有效代碼的第一行(注釋不算)
代碼示範:
package cn.itcast; //包的聲明,必須在有效代碼的第一行
import java.util.Scanner;
import java.util.Random;
public class Demo {}
* C: 包的通路
在通路類時,為了能夠找到該類,必須使用含有包名的類全名(包名.類名)。
包名.包名….類名
如: 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 {}
22導入包
* A:導入包
我們每次使用類時,都需要寫很長的包名。很麻煩,我們可以通過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包名.包名.類名;
23權限修飾符
* A 權限修飾符有哪些
在Java中提供了四種通路權限,使用不同的通路權限時,被修飾的内容會有不同的通路權限,
以下表來說明不同權限的通路能力:
public protected default private
同一類中 √ √ √ √
同一包中(子類與無關類) √ √ √
不同包的子類 √ √
不同包中的無關類 √
* B: 小結
歸納一下:在日常開發過程中,編寫的類、方法、成員變量的通路
要想僅能在本類中通路使用private修飾;
要想本包中的類都可以通路不加修飾符即可;
要想本包中的類與其他包中的子類可以通路使用protected修飾
要想所有包中的所有類都可以通路使用public修飾。
注意:如果類用public修飾,則類名必須與檔案名相同。一個檔案中隻能有一個public修飾的類。
24代碼塊
* A: 概述:
程式中用大括号括起來的代碼叫代碼塊
* B: 分類
局部代碼塊 構造代碼塊 靜态代碼塊 同步代碼塊
* C 局部代碼塊:
局部代碼塊是定義在方法或語句中
特點:
以”{}”劃定的代碼區域,此時隻需要關注作用域的不同即可
方法和類都是以代碼塊的方式劃定邊界的
class Demo{
public static void main(String[] args) {
{
int x = 1;
System.out.println("普通代碼塊" + x);
}
int x = 99;
System.out.println("代碼塊之外" + x);
}
}
結果:
普通代碼塊1
代碼塊之外99
局部代碼塊作用:可以限定變量的聲明周期.
* D: 構造代碼塊
構造代碼塊是定義在類中成員位置的代碼塊
特點:
優先于構造方法執行,構造代碼塊用于執行所有對象均需要的初始化動作
每建立一個對象均會執行一次構造代碼塊。
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);
}
}
* E: 靜态代碼塊
靜态代碼塊是定義在成員位置,使用static修飾的代碼塊。
特點:
它優先于主方法執行、優先于構造代碼塊執行,當以任意形式第一次使用到該類時執行。
該類不管建立多少對象,靜态代碼塊隻執行一次。
可用于給靜态變量指派,用來給類進行初始化。
public class Person {
private String name;
private int age;
//靜态代碼塊
static{
System.out.println("靜态代碼塊執行了");
}
}
* F: 同步代碼塊(多線程學習)
靜态的共享資料
