Java基礎學習 三 (類和物件、類和成員修飾符、this關鍵字、成員的初始化、構造器初始化)
面向物件的基本概念
類和物件
1.類的宣告
[修飾符關鍵字] class 類名 [extends 父類名] [implements 介面1,介面2]{
//類的主體內容
}
public class tt extends Test implements TestInter {
}
2.類的變數成員
變數成員的宣告格式
[修飾關鍵字] 型別 變數名;
public class TT{
public String name;
private int age;
}
3.類的方法成員
宣告格式
[修飾關鍵字] 返回型別 方法名稱( [引數型別和引數列表] ) {
}
public class TT{
//返回字串型別的方法成員
public String method1(){
String name = "name";
return name;
}
//沒有返回值的方法成員
public void method2(){
System.out.println("這是一個沒有返回值的方法成員");
}
}
4.類的構造方法
public class Test { // 構造方法 public Test(){ System.out.println("這是一個無參的建構函式"); } public Test(String n){ System.out.println("帶參的建構函式引數是:"+n); } public static void main(String[] args) { Test t = new Test(); Test tt = new Test("李四"); } }
如果不需要構造方法 可以不寫 編譯器會在編譯的時候自動給你加上一個無參的建構函式
如果你自己定義了一個帶參的構造方法 編譯器將不再自動新增無參的構造方法 如果需要無參的構造方法需要手動新增
構造方法的
5.方法過載
過載(overloading) 是在一個類裡面,方法名字相同,而引數不同。返回型別可以相同也可以不同。每個過載的方法(或者建構函式)都必須有一個獨一無二的引數型別列表。最常用的地方就是構造器的過載。方法能夠在同一個類中。無法以返回值型別作為過載函式的區分標準
上面的一個帶引數的構造方法和沒有引數的構造方法就是過載
6.物件
public class Test { // 構造方法 Test(){ System.out.println("這是一個無參的建構函式"); } public Test(String n){ System.out.println("帶參的建構函式引數是:"+n); } public static void main(String[] args) { Test t ; //宣告物件 t= new Test(); //建立物件 } }
類和成員修飾符
修飾符 | 可修飾物件 | 含義 |
---|---|---|
public(訪問修飾符) |
類、介面、成員變數、成員方法 |
任何地方都可以訪問,對訪問無限制。 |
protected(訪問修飾符) | 成員變數、成員方法、內部類 | 同一個包內或者不同包內的子類可以訪問。 |
private(訪問修飾符) | 成員變數、成員方法、內部類 | 同一個類內可以訪問。 |
預設(default)(訪問修飾符) | 同一個包內可以訪問。 | |
static(非訪問修飾符) | 成員變數、成員方法、內部類 |
靜態變數:static 關鍵字用來宣告獨立於物件的靜態變數,無論一個類例項化多少物件,它的靜態變數只有一份拷貝。 靜態變數也被稱為類變數。區域性變數不能被宣告為 static 變數。 靜態方法:static 關鍵字用來宣告獨立於物件的靜態方法。靜態方法不能使用類的非靜態變數。靜態方法從引數列表得到資料,然後計算這些資料。 靜態內部類:靜態內部類不能夠直接對外呼叫,獨立於該類的任何例項物件。 靜態變數和靜態方法的使用:類名.方法名 或 類名.變數名 只能用於類中的變數和方法 |
final(非訪問修飾符) | 類、成員變數、成員方法 |
final 變數:變數一旦賦值後,不能被重新賦值。被 final 修飾的例項變數必須顯式指定初始值。 final 修飾符通常和 static 修飾符一起使用來建立類常量。 final 方法:類中的 final 方法可以被子類繼承,但是不能被子類修改重寫。 宣告 final 方法的主要目的是防止該方法的內容被修改。 final 類:final 類不能被繼承。 |
abstract(非訪問修飾符) |
類、成員方法 |
抽象類:抽象類不能用來例項化物件,宣告抽象類的唯一目的是為了將來對該類進行擴充。 一個類不能同時被 abstract 和 final 修飾。如果一個類包含抽象方法,那麼該類一定要宣告為抽象類,否則將出現編譯錯誤。介面是一個完全的抽象類 抽象方法:抽象方法是一種沒有任何實現的方法,該方法的的具體實現由子類提供。 抽象方法不能被宣告成 final 和 static。 任何繼承抽象類的子類必須實現父類的所有抽象方法,除非該子類也是抽象類。 如果一個類包含若干個抽象方法,那麼該類必須宣告為抽象類。抽象類可以不包含抽象方法。 |
synchronized(非訪問修飾符) | 成員方法 | synchronized 關鍵字宣告的方法同一時間只能被一個執行緒訪問。synchronized 修飾符可以應用於四個訪問修飾符。 |
transient(非訪問修飾符) |
成員變數 |
序列化的物件包含被 transient 修飾的例項變數時,java 虛擬機器(JVM)跳過該特定的變數。 該修飾符包含在定義變數的語句中,用來預處理類和變數的資料型別。參考 |
volatile(非訪問修飾符) |
成員變數 | volatile 修飾的成員變數在每次被執行緒訪問時,都強制從共享記憶體中重新讀取該成員變數的值。而且,當成員變數發生變化時,會強制執行緒將變化值回寫到共享記憶體。這樣在任何時刻,兩個不同的執行緒總是看到某個成員變數的同一個值。 |
public class Test {
public static Object a;
static class aa{
aa(){
System.out.println("aa");
}
public void method1(){
System.out.println("靜態內部類");
}
}
public static void main(String[] args) {
Test.a = new Test.aa();
((aa) Test.a).method1();
}
}
this關鍵字
當前物件的引用
public class Test {
String name;
Test(String name){
name = name;
System.out.println("不使用this賦值的引數name="+name+",類屬性name="+this.name);
this.name = name;
System.out.println("使用this賦值的引數name="+name+",類屬性name="+this.name);
}
public static void main(String[] args) {
Test t = new Test("張三");
}
}
public class Test {
int i = 0;
Test method(){
i++;
return this;
}
void getI(){
System.out.println(i);
}
public static void main(String[] args) {
Test t = new Test();
t.method().method().method().getI();
}
}
public class Test {
int i = 10;
void method1(){
Test1.method(this);
}
public static void main(String[] args) {
Test t = new Test();
t.method1();
}
}
class Test1{
static Test method(Test test){
System.out.println("進行邏輯處理,i = "+test.i);
return test;
}
}
在構造器中呼叫構造器
呼叫語句必須放在第一條;
public class Test {
Test(String s){
this(1);
System.out.println("這是字串引數的建構函式s="+s);
}
Test(){
this("字串");
System.out.println("這是無參建構函式");
}
Test(int i){
System.out.println("i="+i);
}
public static void main(String[] args) {
Test t = new Test();
}
}
成員的初始化
類成員初始化
在方法中未初始化的值是不能使用的在編譯時期會報錯
而在類的成員變數中未初始化的值則不會報錯
這是在類裡面的成員變數 會按照資料型別的不同預設賦一個初始值
注意:如果成員變數是非基本資料型別,預設初始值未null ,不能呼叫其方法,否則會報空指標異常
Exception in thread "main" java.lang.NullPointerException
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.method();
}
String i;
AA a;
void method(){
System.out.println("i:"+i);
System.out.println("a:"+a);
System.out.println(i.length()); //會報錯
}
}
class AA{}
指定初始化
public class Test {
public static void main(String[] args) {
Test t = new Test();
}
int g = method2(g); //自引用會報錯
int i = method1();
int b = method2(i); //引用其他值不會報錯
int method1(){
return 12;
}
int method2(int a){
return 12+a;
}
}
構造器初始化
初始化順序
public class Test {
public static void main(String[] args) {
System.out.println("執行main");
House house = new House();
house.method();
House.stMethod();
}
static House house2 = new House();
House house3 = new House();
}
class Window {
Window(int i) {
System.out.println("Window(" + i + ")");
}
}
class House {
Window w1 = new Window(1);
House() {
System.out.println("House()");
w3 = new Window(33);
}
static Window w4 = new Window(4);
Window w2 = new Window(2);
static void stMethod() {
System.out.println("stMethod()");
}
void method() {
System.out.println("method()");
}
Window w3 = new Window(3);
{
System.out.println("程式碼塊");
}
static {
System.out.println("靜態程式碼塊");
}
}
初始化循序 1靜態成員變數和靜態程式碼塊 3main方法 4成員變數 5非靜態程式碼塊 67建構函式體中成 7呼叫的方法(靜態和非靜態)
靜態成員變數和靜態程式碼塊初始化後重新建立物件時不會再次初始化,同一級別那個在前那個初始化。直接訪問靜態成員也會使靜態程式碼塊初始化。