靜態方法中只能調用靜態方法,不能調用非靜態。
可以通過創建對象調用非靜態方法
class ArrayDemo{
public static void main(String arg[]){
...........
//靜態方法
//printArray(arr);
//非靜態方法
ArrayDemo ad =new ArrayDemo();
ad.printArray(arr);
.......
}
//public static void printArray(int[] arr){
.....
}
public void printArray(int[] arr){
.....
}
}
在同一個文件夾下,類定義在兩個文件中和定義在一個文件中,其實是一樣的。
虛擬機自動編譯其餘類文件。。。
**把構造方法私有,外界就不能在創建對象了。。。所以只能通過靜態訪問。
2 說明書
/**
* 這是針對數組進行操作的工具類
* @author XXX
* @version V.1
*/
* 這是遍歷數組的方法,遍歷後的格式是:{元素1,元素2,元素3}
* @param arr 這是要被遍歷的數組
*/
/**
* 這是獲取數組中最大值的方法
* @param arr 這是要獲取最大值得數組的數組
* @return 返回數組中的最大值
*/
javadoc -d 目錄 -author -version ArrayTool.java
3 jdk文檔
(1) java.lang 包下的類不需要導入,其他的全部需要導入
要導入:
java.util.Scanner
(2) 記住看類的版本
(3) 類的結構
成員變量 字段摘要
構造方法 構造方法摘要
成員方法 方法摘要
(4) 學習構造方法
A:有構造方法 就創建對象
B:沒有構造方法 成員可能都是靜態的
(5) 看成員方法
A:左邊
是否靜態,如果靜態,可以通過類名調用
返回值類型:人家返回什麼,就用什麼接收
B:右邊
看方法名:方法名稱不要寫錯
參數列表:需要什麼,給什麼,需要幾個,給幾個
4 代碼塊
代碼塊:在java中,使用{}括起來的代碼被稱爲代碼塊
根據位置和聲明的不同,可以分爲
局部代碼塊:局部位置,用於限定變量的生命週期
構造代碼塊: 在類中的成員位置,用{}括起來的代碼,每次調用構造方法執行前,都會執行構造代碼塊。
作用:可以把多個構造方法中的共同代碼放到一起。
靜態代碼塊:在類中的成員位置,用{}括起來的代碼,只不過使用static修飾了,在有main方法的類中,優先於main執行。
作用:一般是對類進行初始化
***面試題?
靜態代碼塊,構造代碼塊,構造方法的執行順序
靜態代碼塊---構造代碼塊----構造方法
靜態代碼塊:只執行一次。構造代碼塊:每次調用都執行。
//靜態代碼塊
static{
int a = 1000;
System.out.println(a);
}
//構造代碼塊
{
int x = 10;
System.out.println(x);
}
//構造方法
public Code(){
System.out.println("code");
}
//構造方法
public Code(int a){
System.out.println("code");
}
}
class CodeDemo{
public static void main(String arg[]){
//局部代碼塊
{
int x = 10;
System.out.println(x);
}
//找不到符號
System.out.println(x);
}
***5 看程序寫結果
class Student{
static{
System.out.println("Student 靜態代碼塊");
}
{
System.out.println("Student 構造代碼塊");
}
public Student(){
System.out.println("Student 構造方法");
}
}
class StudentDemo{
static{
System.out.println("StudentDemo 靜態代碼塊");
}
public static void main(String[] args){
System.out.println("main方法");
Student s1 = new Student();
Student s2 = new Student();
}
}
執行結果:
StudentDemo 靜態代碼塊
main方法
Student 靜態代碼塊
Student 構造代碼塊
Student 構造方法
Student 構造代碼塊
Student 構造方法
6 java中繼承
(1)java繼承特點
A:java只支持單繼承,不支持多繼承
B:java支持多層繼承
(2)java繼承注意事項
A:子類只能繼承父類所有非私有的成員(成員方法和成員變量)
**(其實這也體現了繼承的另一個弊端:打破了封裝性)
B:子類不能繼承父類的構造方法,但是可以通過super關鍵字去訪問父類的構造方法。
C:不要爲了部分功能而去繼承
(3)java繼承中成員變量的關係
A:子類中的成員變量和父類中的成員變量名稱不一樣時。
B:子類中的成員變量和父類中的成員變量名稱一樣時,就近原則。
(4)java繼承中構造方法的關係
A:子類中所有構造方法默認都會訪問父類中空參數的構造方法
B:爲什麼?
因爲子類會繼承父類中的數據,可能還會使用父類的數據。
所以,子類初始化之前,一定要先完成父類數據的初始化。
**注意:子類每一個構造方法的第一條語句默認都是:super();
(5)java繼承中構造方法的注意事項
如果父類沒有無參數的構造方法,那麼子類的構造方法會出現什麼現象呢?
報錯!
如何解決?
A:在父類中加一個無參數的構造方法。
B: 通過使用super關鍵字去顯示的調用父類的帶參構造方法
C:子類通過this去調用本類的其他構造方法
子類中一定要有一個去訪問了父類的構造方法,否則父類數據就沒有初始化
**注意事項:super()或者this()必須出現在第一條語句上
否則,就會有父類數據的多次初始化
(6)java繼承中成員方法的關係:
A:子類中的方法和父類中的方法聲明不一樣時。
B:子類中的方法和父類中的方法聲明一樣時。
通過子類調用方法:
a:先找子類中,有沒有這個方法,有就使用。
b:再看父類中,有沒有這個方法,有就使用。
c:如果都沒有就報錯。
***7 繼承中的面試題
A:成員變量的問題
int x = 10; //成員變量是基本類型
Student s = new Student(); //成員變量是引用類型
B:一個類的初始化過程
成員變量的初始化
默認初始化
顯示初始化
構造方法初始化
C:子父類的初始化(分層初始化)
先進行父類初始化,然後進行子類初始化
class X{
Y b = new Y();
X(){
System.out.print("X");
}
}
class Y{
Y(){
System.out.print("Y");
}
}
public class Z extends X{
Y y = new Y();
Z(){
//super();
System.out.print("Z");
}
public static void main(String[] args){
new Z();
}
}
輸出結果: YXYZ
有super出現問題:
雖然子類中構造方法默認有一個super();
初始化的時候,不是按照那個順序進行的。
而是按照分層初始化進行的。
它僅僅表示要先初始化父類數據,再初始化子類數據
8 重寫
(1)方法重寫
子類中出現了和父類中方法聲明一模一樣的方法。
方法重載
本類中出現的方法名一樣,參數列表不同的方法,與返回值無關。
(2)方法重寫的注意事項
A:父類中私有方法不能被重寫
因爲父類私有方法子類根本就無法繼承
***B:子類重寫父類方法時,訪問權限不能更低
最好就一致
C:父類靜態方法,子類也必須通過靜態方法進行重寫
其實這個算不上重寫,但現象確實如此,多態中會介紹。
java中靜態變量和靜態方法可以被繼承,但是沒有被重寫而是被隱藏。
通過子類調用父類的同名的靜態成員變量或方法,依然訪問的是父類的變量和方法。
而且,靜態不能使用this和super關鍵字。
(1)方法重寫(Override)和方法重載(Overload)的區別?方法重載能改變返回值類型嗎?
方法重寫:在子類中,出現和父類中一模一樣的方法聲明的現象。
方法重載:同一個類中,出現的方法名相同,參數列表不同的現象。
方法重載能改變返回值類型,因爲它和返回值類型無關。
(2)this關鍵字和super關鍵字分別代表什麼?以及他們各自的使用場景和作用。
this:代表當前類的對象引用
super:代表父類存儲空間的標識(可以理解爲父類的引用,通過這個東西可以訪問父類的成員)
場景:
成員變量:
this.成員變量
super.成員變量
構造方法:
this(...)
super(...)
成員方法:
this.成員方法
super.成員方法
10 final
(1)由於繼承中方法有一個現象:方法重寫
所以,父類的功能,就會被子類給覆蓋掉。
有些時候,我們不想讓子類去覆蓋掉父類的功能,只能讓他使用
這個時候,針對這種情況,java就提供了一個關鍵字final
(2) final 可以修飾類,方法,變量
特點:
final可以修飾類,該類不能被繼承
final可以修飾方法,該方法不能被重寫
final可以修飾變量,該變量不能被重新賦值,因爲這個變量其實是常量。
(3) 常量
A:字面值常量
" hello" ,10,true
B:自定義常量
final int x = 10
***11 final面試題
(1) final修飾局部變量的問題
基本類型:基本類型的值不能發生改變引用類型:引用類型的地址值不能發生改變,但是該對象的堆內存的值可以發生改變
class Student{int age =10;
}
class FianlTest{
public static void main(String[] args){
//局部變量是基本數據類型
final int y = 10;
//無法爲最終變量y分配值
//y = 100;
//局部變量是引用類型
Studnet s = new Student();
System.out.println(s.age);
s.age = 100;
System.out.println(s.age);
//輸出 10 100
final Student ss =new Student();
System.out.println(ss.age);
ss.age = 100;
System.out.println(ss.age);
//輸出 10 100
//重新分配內存空間
//報錯,無法爲最終變量ss分配值
ss = new Student();
A:被final修飾的變量只能賦值一次
B:在構造方法完畢前。(非靜態的常量)
A:
class Demo{
int num = 10;
final int num2 = 20;
public Demo(){
num = 100;
}
}
class FinalTest2{
public static void main(String[] args){
Demo d = new Demo();
System.out.println(d.num);
}
}
輸出結果爲:100 (先初始化成員變量,再初始化構造方法)
B:
class Demo{
int num = 10;
final int num2 = 20;
public Demo(){
num = 100;
//無法爲最終變量num2分配值 會報錯
num2 = 200
}
}
class FinalTest2{
public static void main(String[] args){
Demo d = new Demo();
System.out.println(d.num);
System.out.println(d.num2);
}
}
輸出結果:報錯
C:
class Demo{
//int num = 10;
//final int num2 = 20;
int num;
final int num2 ;
public Demo(){
num = 100;
num2 = 200
}
}
class FinalTest2{
public static void main(String[] args){
Demo d = new Demo();
System.out.println(d.num);
System.out.println(d.num2);
}
}
輸出結果:100 200
D:
class Demo{
int num;
final int num2 ;
{
num2= 10;
}
public Demo(){
num = 100;
num2 = 200
}
}
class FinalTest2{
public static void main(String[] args){
Demo d = new Demo();
System.out.println(d.num);
System.out.println(d.num2);
}
}
輸出結果:報錯 (代碼塊中已經賦值了)