java基礎(chǔ)

數(shù)據(jù)類型

  • 數(shù)據(jù)類型分類
    基本數(shù)據(jù)類型:包括 整數(shù) 、 浮點(diǎn)數(shù) 、 字符 、 布爾
    引用數(shù)據(jù)類型:包括 類 、 數(shù)組 、 接口
    基本數(shù)據(jù)類型:四類八種

    數(shù)據(jù)類型 關(guān)鍵字 內(nèi)存占用 取值范圍
    字節(jié)型 byte 1個(gè)字節(jié) -128~127
    短整型 short 2個(gè)字節(jié) -32768~32767
    整型 int(默認(rèn)) 4個(gè)字節(jié) -231次方~2的31次方-1
    長整型 long 8個(gè)字節(jié) -2的63次方~2的63次方-1
    單精度浮點(diǎn)數(shù) float 4個(gè)字節(jié) 1.4013E-45~3.4028E+38
    雙精度浮點(diǎn)數(shù) double(默認(rèn)) 8個(gè)字節(jié) 4.9E-324~1.7977E+308
    字符型 char 2個(gè)字節(jié) 0-65535
    布爾類型 boolean 1個(gè)字節(jié) true,false

    注意:
    long類型:建議數(shù)據(jù)后加L表示。
    float類型:建議數(shù)據(jù)后加F表示。

  • 自動(dòng)轉(zhuǎn)換規(guī)則

    byte、short、char‐‐>int‐‐>long‐‐>float‐‐>double

  • 強(qiáng)制轉(zhuǎn)換

    將 1.5 賦值到 int 類型變量會(huì)發(fā)生什么?產(chǎn)生編譯失敗,肯定無法賦值。

    ? int i = 1.5; // 錯(cuò)誤

    強(qiáng)制類型轉(zhuǎn)換:將 取值范圍大的類型 強(qiáng)制轉(zhuǎn)換成 取值范圍小的類型 。 比較而言,自動(dòng)轉(zhuǎn)換是Java自動(dòng)執(zhí)行的,而強(qiáng)制轉(zhuǎn)換需要我們自己手動(dòng)行。 轉(zhuǎn)換格式 :數(shù)據(jù)類型 變量名 = (數(shù)據(jù)類型)被轉(zhuǎn)數(shù)據(jù)值;

    ? int i = (int)1.5

    /*
    強(qiáng)制類型轉(zhuǎn)換
      1. 特點(diǎn):代碼需要進(jìn)行特殊的格式處理,不能自動(dòng)完成。
      2. 格式:范圍小的類型 范圍小的變量名 = (范圍小的類型) 原本范圍大的數(shù)據(jù);
    
    注意事項(xiàng):
      1. 強(qiáng)制類型轉(zhuǎn)換一般不推薦使用,因?yàn)橛锌赡馨l(fā)生精度損失、數(shù)據(jù)溢出。
      2. byte/short/char這三種類型都可以發(fā)生數(shù)學(xué)運(yùn)算,例如加法“+”.
      3. byte/short/char這三種類型在運(yùn)算的時(shí)候,都會(huì)被首先提升成為int類型,然后再計(jì)算。
      4. boolean類型不能發(fā)生數(shù)據(jù)類型轉(zhuǎn)換
    */
    public class Demo02DataType {
      public static void main(String[] args) {
          // 左邊是int類型,右邊是long類型,不一樣
          // long --> int,不是從小到大
          // 不能發(fā)生自動(dòng)類型轉(zhuǎn)換!
          // 格式:范圍小的類型 范圍小的變量名 = (范圍小的類型) 原本范圍大的數(shù)據(jù);
          int num = (int) 100L;
          System.out.println(num);
          
          // long強(qiáng)制轉(zhuǎn)換成為int類型
          int num2 = (int) 6000000000L;
          System.out.println(num2); // 1705032704
          
          // double --> int,強(qiáng)制類型轉(zhuǎn)換
          int num3 = (int) 3.99;
          System.out.println(num3); // 3,這并不是四舍五入,所有的小數(shù)位都會(huì)被舍棄掉
          
          char zifu1 = 'A'; // 這是一個(gè)字符型變量,里面是大寫字母A
          System.out.println(zifu1 + 1); // 66,也就是大寫字母A被當(dāng)做65進(jìn)行處理
          // 計(jì)算機(jī)的底層會(huì)用一個(gè)數(shù)字(二進(jìn)制)來代表字符A,就是65
          // 一旦char類型進(jìn)行了數(shù)學(xué)運(yùn)算,那么字符就會(huì)按照一定的規(guī)則翻譯成為一個(gè)數(shù)字
          
          byte num4 = 40; // 注意!右側(cè)的數(shù)值大小不能超過左側(cè)的類型范圍
          byte num5 = 50;
          // byte + byte --> int + int --> int
          int result1 = num4 + num5;
          System.out.println(result1); // 90
          
          short num6 = 60;
          // byte + short --> int + int --> int
          // int強(qiáng)制轉(zhuǎn)換為short:注意必須保證邏輯上真實(shí)大小本來就沒有超過short范圍,否則會(huì)發(fā)生數(shù)據(jù)溢出
          short result2 = (short) (num4 + num6);
          System.out.println(result2); // 100
      }
    }
    

運(yùn)算符和變量、常量

  • +=符號的擴(kuò)展

    public static void main(String[] args){
    short s = 1;
    s+=1;
    System.out.println(s);
    }
    

    分析: s += 1 邏輯上看作是 s = s + 1 計(jì)算結(jié)果被提升為int類型,再向short類型賦值時(shí)發(fā)生錯(cuò)誤,因?yàn)椴荒軐⑷≈捣秶?大的類型賦值到取值范圍小的類型。但是, s=s+1進(jìn)行兩次運(yùn)算 , += 是一個(gè)運(yùn)算符,只運(yùn)算一次,并帶有強(qiáng)制轉(zhuǎn)換的特點(diǎn), 也就是說 s += 1 就是 s = (short)(s + 1) ,因此程序沒有問題編譯通過,運(yùn)行結(jié)果是2

  • 常量和變量的運(yùn)算

    public static void main(String[] args){
    byte b1=1;
    byte b2=2;
    byte b3=1 + 2;
    byte b4=b1 + b2;
    System.out.println(b3);
    System.out.println(b4);
    }
    

    分析: b3 = 1 + 2 , 1 和 2 是常量,為固定不變的數(shù)據(jù),在編譯的時(shí)候(編譯器javac),已經(jīng)確定了 1+2 的結(jié)果并沒 有超過byte類型的取值范圍,可以賦值給變量 b3 ,因此 b3=1 + 2 是正確的。

    反之, b4 = b2 + b3 , b2 和 b3 是變量,變量的值是可能變化的,在編譯的時(shí)候,編譯器javac不確定b2+b3的結(jié)果是什 么,因此會(huì)將結(jié)果以int類型進(jìn)行處理,所以int類型不能賦值給byte類型,因此編譯失敗

Idea 常用快捷鍵

快捷鍵 功能
Alt+Enter 導(dǎo)入包,自動(dòng)修正代碼
Ctrl+Y 刪除光標(biāo)所在行
Ctrl+D 復(fù)制光標(biāo)所在行的內(nèi)容,插入光標(biāo)位置下面
Ctrl+Alt+L 格式化代碼
Ctrl+/ 單行注釋
Ctrl+Shift+/ 選中代碼注釋,多行注釋,再按取消注釋
Alt+Ins 自動(dòng)生成代碼,toString,get,set等方法
Alt+Shift+上下箭頭 移動(dòng)當(dāng)前代碼行

數(shù)組

  • 定義數(shù)組的三種方式

    int[] arr = new int[3];
    int[] arr = new int[]{1,2,3,4,5};
    int[] arr = {1,2,3,4,5};
    

    數(shù)組的長度屬性arr.length

類和對象

數(shù)據(jù)類型 默認(rèn)值
基本類型 整數(shù)(byte,short,int,long) 0
浮點(diǎn)數(shù)(float,double) 0.0
字符(char) '\u0000'
布爾(boolean) false
引用類型 數(shù)組,類,接口 null

常用API

  • Scanner類

    import java.util.Scanner;
    public class Demo01_Scanner {
      public static void main(String[] args) {
            //2. 創(chuàng)建鍵盤錄入數(shù)據(jù)的對象
            Scanner sc = new Scanner(System.in);
            //3. 接收數(shù)據(jù)
            System.out.println("請錄入一個(gè)整數(shù):");
            int i = sc.nextInt();
            //4. 輸出數(shù)據(jù)
            System.out.println("i:"+i);
        }
    }
    
  • 匿名對象

    創(chuàng)建對象時(shí),只有創(chuàng)建對象的語句,卻沒有把對象地址值賦值給某個(gè)變量。雖然是創(chuàng)建對象的簡化寫法,但是應(yīng)用 場景非常有限。

    匿名對象 :沒有變量名的對象。

    一旦調(diào)用兩次方法,就是創(chuàng)建了兩個(gè)對象,造成浪費(fèi)。一般可作為方法的參數(shù)和返回值

    new Scanner(System.in).nextInt();
    new Scanner(System.in).nextInt();
    
  • Random類

    public int nextInt(int n):返回一個(gè)偽隨機(jī)數(shù),范圍在 0 (包括)和 指定值 n (不包括)之間的 int 值。

    //1. 導(dǎo)包
    import java.util.Random;
    public class Demo01_Random {
        public static void main(String[] args) {
            //2. 創(chuàng)建鍵盤錄入數(shù)據(jù)的對象
            Random r = new Random();
            for(int i = 0; i < 3; i++){
                //3. 隨機(jī)生成一個(gè)數(shù)據(jù)
                int number = r.nextInt(10);
                //4. 輸出數(shù)據(jù)
                System.out.println("number:"+ number);
            }
        }
    }
    
  • ArrayList類

    java.util.ArrayList 是大小可變的數(shù)組的實(shí)現(xiàn),存儲(chǔ)在內(nèi)的數(shù)據(jù)稱為元素。此類提供一些方法來操作內(nèi)部存儲(chǔ) 的元素。 ArrayList 中可不斷添加元素,其大小也自動(dòng)增長。

    public class Test02StudentArrayList {
        public static void main(String[] args) {
            //創(chuàng)建學(xué)生數(shù)組
            ArrayList<String> list = new ArrayList<>();
            //創(chuàng)建學(xué)生對象
            String s1 = "曹操";
            String s2 = "劉備";
            String s3 = "孫權(quán)";
            //打印學(xué)生ArrayList集合
            System.out.println(list);
            //把學(xué)生對象作為元素添加到集合
            list.add(s1);
            list.add(s2);
            list.add(s3);
            //打印學(xué)生ArrayList集合
            System.out.println(list);
        }
    }
    

    常用方法:

    public boolean add(E e):將指定的元素添加到此集合的尾部。

    public E remove(int index) :移除此集合中指定位置上的元素。返回被刪除的元素。

    public E get(int index):返回此集合中指定位置上的元素。返回獲取的元素。

    public int size():返回此集合中的元素?cái)?shù)。遍歷集合時(shí),可以控制索引范圍,防止越界。

  • String類
    1.構(gòu)造方法

public String() :初始化新創(chuàng)建的 String對象,以使其表示空字符序列。
public String(char[] value) :通過當(dāng)前參數(shù)中的字符數(shù)組來構(gòu)造新的String。
public String(byte[] bytes) :通過使用平臺(tái)的默認(rèn)字符集解碼當(dāng)前參數(shù)中的字節(jié)數(shù)組來構(gòu)造新的String。
2.常用方法
判斷功能:
public boolean equals (Object anObject) :將此字符串與指定對象進(jìn)行比較。
public boolean equalsIgnoreCase (String anotherString) :將此字符串與指定對象進(jìn)行比較,忽略大小寫。
獲取功能:
public int length () :返回此字符串的長度。
public String concat (String str) :將指定的字符串連接到該字符串的末尾。
public char charAt (int index) :返回指定索引處的 char值。
public int indexOf (String str):返回指定子字符串第一次出現(xiàn)在該字符串內(nèi)的索引。
public String substring (int beginIndex) :返回一個(gè)子字符串,從beginIndex開始截取字符串到字符串結(jié)尾。
public String substring (int beginIndex, int endIndex) :返回一個(gè)子字符串,從beginIndex到endIndex截取字符串。含beginIndex,不含endIndex。
轉(zhuǎn)換功能:
public char[] toCharArray ():將此字符串轉(zhuǎn)換為新的字符數(shù)組。
public byte[] getBytes ():使用平臺(tái)的默認(rèn)字符集將該 String編碼轉(zhuǎn)換為新的字節(jié)數(shù)組。
public String replace (CharSequence target, CharSequence replacement):將與target匹配的字符串使用replacement字符串替換。
分割功能:
public String[] split(String regex):將此字符串按照給定的regex(規(guī)則)拆分為字符串?dāng)?shù)組。

public class String_Demo03 {
    public static void main(String[] args) {
        //創(chuàng)建字符串對象
        String s = "aa|bb|cc";
        String[] strArray = s.split("|"); // ["aa","bb","cc"]

        for(int x = 0; x < strArray.length; x++) {
            System.out.println(strArray[x]); // aa bb cc
        }
    }
}
  • static 關(guān)鍵字
    關(guān)于 static 關(guān)鍵字的使用,它可以用來修飾的成員變量和成員方法,被修飾的成員是屬于類的,而不是單單是屬于某個(gè)對象的。也就是說,既然屬于類,就可以不靠創(chuàng)建對象來調(diào)用了。
    1.類變量:使用 static關(guān)鍵字修飾的成員變量。
    static 數(shù)據(jù)類型 變量名;
    static int numberID;
    2.類方法:即靜態(tài)方法
    當(dāng) static 修飾成員方法時(shí),該方法稱為類方法 。靜態(tài)方法在聲明中有 static ,建議使用類名來調(diào)用,而不需要?jiǎng)?chuàng)建類的對象。
    靜態(tài)方法調(diào)用的注意事項(xiàng):
    靜態(tài)方法可以直接訪問類變量和靜態(tài)方法。
    靜態(tài)方法不能直接訪問普通成員變量或成員方法。反之,成員方法可以直接訪問類變量或靜態(tài)方法。
    靜態(tài)方法中,不能使用this關(guān)鍵字。
    3.靜態(tài)代碼塊
    靜態(tài)代碼塊:定義在成員位置,使用static修飾的代碼塊{ }。
    位置:類中方法外。
    執(zhí)行:隨著類的加載而執(zhí)行且執(zhí)行一次,優(yōu)先于main方法和構(gòu)造方法的執(zhí)行。
    格式:
public class ClassName{
    static {
        // 執(zhí)行語句
    }
}

static 關(guān)鍵字,可以修飾變量、方法和代碼塊。在使用的過程中,其主要目的還是想在不創(chuàng)建對象的情況下,去調(diào)用方法。

  • Object類
    public String toString():返回該對象的字符串表示。
    public boolean equals(Object obj):指示其他某個(gè)對象是否與此對象“相等”。

  • Objects類
    JDK7添加了一個(gè)Objects工具類,它提供了一些方法來操作對象,它由一些靜態(tài)的實(shí)用方法組成,這些方法是null-save(空指針安全的)或null-tolerant(容忍空指針的),用于計(jì)算對象的hashcode、返回對象的字符串表示形式、比較兩個(gè)對象。

在比較兩個(gè)對象的時(shí)候,Object的equals方法容易拋出空指針異常,而Objects類中的equals方法就優(yōu)化了這個(gè)問題。方法如下:

public static boolean equals(Object a, Object b):判斷兩個(gè)對象是否相等。

我們可以查看一下源碼,學(xué)習(xí)一下:

public static boolean equals(Object a, Object b) {  
    return (a == b) || (a != null && a.equals(b));  
}
  • Date類
    public Date():分配Date對象并初始化此對象,以表示分配它的時(shí)間(精確到毫秒)。
    public Date(long date):分配Date對象并初始化此對象,以表示自從標(biāo)準(zhǔn)基準(zhǔn)時(shí)間(稱為“歷元(epoch)”,即1970年1月1日00:00:00 GMT)以來的指定毫秒數(shù)。
import java.util.Date;

public class Demo01Date {
    public static void main(String[] args) {
        // 創(chuàng)建日期對象,把當(dāng)前的時(shí)間
        System.out.println(new Date()); // Tue Jan 16 14:37:35 CST 2018
        // 創(chuàng)建日期對象,把當(dāng)前的毫秒值轉(zhuǎn)成日期對象
        System.out.println(new Date(0L)); // Thu Jan 01 08:00:00 CST 1970
    }
}

tips:在使用println方法時(shí),會(huì)自動(dòng)調(diào)用Date類中的toString方法。Date類對Object類中的toString方法進(jìn)行了覆蓋重寫,所以結(jié)果為指定格式的字符串。
public long getTime() 把日期對象轉(zhuǎn)換成對應(yīng)的時(shí)間毫秒值。

  • DateFormat類
    格式化:按照指定的格式,從Date對象轉(zhuǎn)換為String對象。
    解析:按照指定的格式,從String對象轉(zhuǎn)換為Date對象。
    由于DateFormat為抽象類,不能直接使用,所以需要常用的子類java.text.SimpleDateFormat。這個(gè)類需要一個(gè)模式(格式)來指定格式化或解析的標(biāo)準(zhǔn)。構(gòu)造方法為:
  • public SimpleDateFormat(String pattern):用給定的模式和默認(rèn)語言環(huán)境的日期格式符號構(gòu)造SimpleDateFormat。參數(shù)pattern是一個(gè)字符串,代表日期時(shí)間的自定義格式。
    常用的格式規(guī)則為:
標(biāo)識字母(區(qū)分大小寫) 含義
y
M
d
H 時(shí)
m
s
import java.text.DateFormat;
import java.text.SimpleDateFormat;

public class Demo02SimpleDateFormat {
    public static void main(String[] args) {
        // 對應(yīng)的日期格式如:2018-01-16 15:06:38
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    }    
}

DateFormat類的常用方法有:
public String format(Date date):將Date對象格式化為字符串。
public Date parse(String source):將字符串解析為Date對象。

  • System類
    java.lang.System類中提供了大量的靜態(tài)方法,可以獲取與系統(tǒng)相關(guān)的信息或系統(tǒng)級操作,在System類的API文檔中,常用的方法有:
    public static long currentTimeMillis():返回以毫秒為單位的當(dāng)前時(shí)間。
    public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length):將數(shù)組中指定的數(shù)據(jù)拷貝到另一個(gè)數(shù)組中。

實(shí)際上,currentTimeMillis方法就是 獲取當(dāng)前系統(tǒng)時(shí)間與1970年01月01日00:00點(diǎn)之間的毫秒差值

import java.util.Date;

public class SystemDemo {
    public static void main(String[] args) {
        //獲取當(dāng)前時(shí)間毫秒值
        System.out.println(System.currentTimeMillis()); // 1516090531144
    }
}

將src數(shù)組中前3個(gè)元素,復(fù)制到dest數(shù)組的前3個(gè)位置上復(fù)制元素前:src數(shù)組元素[1,2,3,4,5],dest數(shù)組元素[6,7,8,9,10]復(fù)制元素后:src數(shù)組元素[1,2,3,4,5],dest數(shù)組元素[1,2,3,9,10]

import java.util.Arrays;

public class Demo11SystemArrayCopy {
    public static void main(String[] args) {
        int[] src = new int[]{1,2,3,4,5};
        int[] dest = new int[]{6,7,8,9,10};
        System.arraycopy( src, 0, dest, 0, 3);
        /*代碼運(yùn)行后:兩個(gè)數(shù)組中的元素發(fā)生了變化
         src數(shù)組元素[1,2,3,4,5]
         dest數(shù)組元素[1,2,3,9,10]
        */
    }
}
  • StringBuilder類
    StringBuilder是個(gè)字符串的緩沖區(qū),即它是一個(gè)容器,容器中可以裝很多字符串。并且能夠?qū)ζ渲械淖址M(jìn)行各種操作。
    根據(jù)StringBuilder的API文檔,常用構(gòu)造方法有2個(gè):
    public StringBuilder():構(gòu)造一個(gè)空的StringBuilder容器。
    public StringBuilder(String str):構(gòu)造一個(gè)StringBuilder容器,并將字符串添加進(jìn)去。

StringBuilder常用的方法有2個(gè):
public StringBuilder append(...):添加任意類型數(shù)據(jù)的字符串形式,并返回當(dāng)前對象自身。
public String toString():將當(dāng)前StringBuilder對象轉(zhuǎn)換為String對象。

append方法具有多種重載形式,可以接收任意類型的參數(shù)。任何數(shù)據(jù)作為參數(shù)都會(huì)將對應(yīng)的字符串內(nèi)容添加到StringBuilder中。例如:

public class Demo02StringBuilder {
    public static void main(String[] args) {
        //創(chuàng)建對象
        StringBuilder builder = new StringBuilder();
        //public StringBuilder append(任意類型)
        StringBuilder builder2 = builder.append("hello");
        //對比一下
        System.out.println("builder:"+builder);
        System.out.println("builder2:"+builder2);
        System.out.println(builder == builder2); //true
        // 可以添加 任何類型
        builder.append("hello");
        builder.append("world");
        builder.append(true);
        builder.append(100);
        // 在我們開發(fā)中,會(huì)遇到調(diào)用一個(gè)方法后,返回一個(gè)對象的情況。然后使用返回的對象繼續(xù)調(diào)用方法。
        // 這種時(shí)候,我們就可以把代碼現(xiàn)在一起,如append方法一樣,代碼如下
        //鏈?zhǔn)骄幊?        builder.append("hello").append("world").append(true).append(100);
        System.out.println("builder:"+builder);
    }
}

備注:StringBuilder已經(jīng)覆蓋重寫了Object當(dāng)中的toString方法。
通過toString方法,StringBuilder對象將會(huì)轉(zhuǎn)換為不可變的String對象。如:

public class Demo16StringBuilder {
    public static void main(String[] args) {
        // 鏈?zhǔn)絼?chuàng)建
        StringBuilder sb = new StringBuilder("Hello").append("World").append("Java");
        // 調(diào)用方法
        String str = sb.toString();
        System.out.println(str); // HelloWorldJava
    }
}
  • 包裝類
    基本數(shù)值---->包裝對象
    Integer i = new Integer(4);//使用構(gòu)造函數(shù)函數(shù)
    Integer iii = Integer.valueOf(4);//使用包裝類中的valueOf方法

包裝對象---->基本數(shù)值
int num = i.intValue();

由于我們經(jīng)常要做基本類型與包裝類之間的轉(zhuǎn)換,從Java 5(JDK 1.5)開始,基本類型與包裝類的裝箱、拆箱動(dòng)作可以自動(dòng)完成。例如:

Integer i = 4;//自動(dòng)裝箱。相當(dāng)于Integer i = Integer.valueOf(4);
i = i + 5;//等號右邊:將i對象轉(zhuǎn)成基本數(shù)值(自動(dòng)拆箱) i.intValue() + 5;
//加法運(yùn)算完成后,再次裝箱,把基本數(shù)值轉(zhuǎn)成對象。

基本類型與字符串之間的轉(zhuǎn)換:
基本類型直接與””相連接即可;如:34+""

String轉(zhuǎn)換成對應(yīng)的基本類型

除了Character類之外,其他所有包裝類都具有parseXxx靜態(tài)方法可以將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的基本類型:
public static byte parseByte(String s):將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的byte基本類型。
public static short parseShort(String s):將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的short基本類型。
public static int parseInt(String s):將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的int基本類型。
public static long parseLong(String s):將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的long基本類型。
public static float parseFloat(String s):將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的float基本類型。
public static double parseDouble(String s):將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的double基本類型。
public static boolean parseBoolean(String s):將字符串參數(shù)轉(zhuǎn)換為對應(yīng)的boolean基本類型。

繼承

  • 格式
class 父類 {
...
}
class 子類 extends 父類 {
...
}
  • 成員變量
    1.如果子類父類中出現(xiàn)不重名的成員變量,這時(shí)的訪問是沒有影響的。
    2.如果子類父類中出現(xiàn)重名的成員變量,這時(shí)的訪問是有影響的。
    子父類中出現(xiàn)了同名的成員變量時(shí),在子類中需要訪問父類中非私有成員變量時(shí),需要使用 super 關(guān)鍵字,修飾父類成員變量,類似于之前學(xué)過的 this 。
class Fu {
  // Fu中的成員變量。
  int num = 5;
} 
class Zi extends Fu {
  // Zi中的成員變量
  int num = 6;
  public void show() {
    // 訪問父類中的num
    System.out.println("Fu num=" + super.num);
    // 訪問子類中的num
    System.out.println("Zi num=" + this.num);
  }
}

class ExtendsDemo03 {
  public static void main(String[] args) {
  // 創(chuàng)建子類對象
  Zi z = new Zi();
    // 調(diào)用子類中的show方法
    z.show();
  }
} 
演示結(jié)果:
Fu num = 5
Zi num = 6

小貼士:Fu 類中的成員變量是非私有的,子類中可以直接訪問。若Fu 類中的成員變量私有了,子類是不能直接訪問的。通常編碼時(shí),我們遵循封裝的原則,使用private修飾成員變量,那么如何訪問父類的私有成員變量呢?對!可以在父類中提供公共的getXxx方法和setXxx方法。

  • 成員方法
    1.如果子類父類中出現(xiàn)不重名的成員方法,這時(shí)的調(diào)用是沒有影響的。對象調(diào)用方法時(shí),會(huì)先在子類中查找有沒有對應(yīng)的方法,若子類中存在就會(huì)執(zhí)行子類中的方法,若子類中不存在就會(huì)執(zhí)行父類中相應(yīng)的方法。
    2.如果子類父類中出現(xiàn)重名的成員方法,這時(shí)的訪問是一種特殊情況,叫做方法重寫 (Override)。
    小貼士:重寫時(shí),用到super.父類成員方法,表示調(diào)用父類的成員方法

注意事項(xiàng)
子類方法覆蓋父類方法,必須要保證權(quán)限大于等于父類權(quán)限。
子類方法覆蓋父類方法,返回值類型、函數(shù)名和參數(shù)列表都要一模一樣。

  • *構(gòu)造方法
  1. 構(gòu)造方法的名字是與類名一致的。所以子類是無法繼承父類構(gòu)造方法的。
  2. 構(gòu)造方法的作用是初始化成員變量的。所以子類的初始化過程中,必須先執(zhí)行父類的初始化動(dòng)作。子類的構(gòu)造方法中默認(rèn)有一個(gè) super() ,表示調(diào)用父類的構(gòu)造方法,父類成員變量初始化后,才可以給子類使用。

this(...) ‐‐ 本類的構(gòu)造方法
super(...) ‐‐ 父類的構(gòu)造方法

子類的每個(gè)構(gòu)造方法中均有默認(rèn)的super(),調(diào)用父類的空參構(gòu)造。手動(dòng)調(diào)用父類構(gòu)造會(huì)覆蓋默認(rèn)的super()。super() 和 this() 都必須是在構(gòu)造方法的第一行,所以不能同時(shí)出現(xiàn)。

抽象類

定義:
抽象方法 : 沒有方法體的方法。
抽象類:包含抽象方法的類。

  • 抽象方法
    使用 abstract 關(guān)鍵字修飾方法,該方法就成了抽象方法,抽象方法只包含一個(gè)方法名,而沒有方法體。
修飾符 abstract 返回值類型 方法名 (參數(shù)列表);
public abstract void run();
  • 抽象類
    如果一個(gè)類包含抽象方法,那么該類必須是抽象類。
abstract class 類名字 {
} 
public abstract class Animal {
  public abstract void run();
}

繼承抽象類的子類必須重寫父類所有的抽象方法。否則,該子類也必須聲明為抽象類。最終,必須有子類實(shí)現(xiàn)該父類的抽象方法,否則,從最初的父類到最終的子類都不能創(chuàng)建對象,失去意義。

注意事項(xiàng)

  1. 抽象類不能創(chuàng)建對象,如果創(chuàng)建,編譯無法通過而報(bào)錯(cuò)。只能創(chuàng)建其非抽象子類的對象。
    理解:假設(shè)創(chuàng)建了抽象類的對象,調(diào)用抽象的方法,而抽象方法沒有具體的方法體,沒有意義。
  2. 抽象類中,可以有構(gòu)造方法,是供子類創(chuàng)建對象時(shí),初始化父類成員使用的。
    理解:子類的構(gòu)造方法中,有默認(rèn)的super(),需要訪問父類構(gòu)造方法。
  3. 抽象類中,不一定包含抽象方法,但是有抽象方法的類必定是抽象類
    理解:未包含抽象方法的抽象類,目的就是不想讓調(diào)用者創(chuàng)建該類對象,通常用于某些特殊的類結(jié)構(gòu)設(shè)計(jì)。
  4. 抽象類的子類,必須重寫抽象父類中所有的抽象方法,否則,編譯無法通過而報(bào)錯(cuò)。除非該子類也是抽象類。
    理解:假設(shè)不重寫所有抽象方法,則類中可能包含抽象方法。那么創(chuàng)建對象后,調(diào)用抽象的方法,沒有意義。

接口

接口,是Java語言中一種引用類型,是方法的集合,如果說類的內(nèi)部封裝了成員變量、構(gòu)造方法和成員方法,那么接口的內(nèi)部主要就是封裝了方法,包含抽象方法(JDK 7及以前),默認(rèn)方法和靜態(tài)方法(JDK 8),私有方法(JDK 9)。
接口的定義,它與定義類方式相似,但是使用 interface 關(guān)鍵字。它也會(huì)被編譯成.class文件,但一定要明確它并不是類,而是另外一種引用數(shù)據(jù)類型。引用數(shù)據(jù)類型:數(shù)組,類,接口。
接口的使用,它不能創(chuàng)建對象,但是可以被實(shí)現(xiàn)( implements ,類似于被繼承)。一個(gè)實(shí)現(xiàn)接口的類(可以看做是接口的子類),需要實(shí)現(xiàn)接口中所有的抽象方法,創(chuàng)建該類對象,就可以調(diào)用方法了,否則它必須是一個(gè)抽象類。
定義格式

public interface 接口名稱 {
  // 抽象方法
  // 默認(rèn)方法
  // 靜態(tài)方法
  // 私有方法
}

/*
含有抽象方法
抽象方法:使用 abstract 關(guān)鍵字修飾,可以省略,沒有方法體。該方法供子類實(shí)現(xiàn)使用。
*/
public interface InterFaceName {
  public abstract void method(); //使用 abstract 關(guān)鍵字修飾,可以省略,沒有方法體。
}

/*
含有默認(rèn)方法和靜態(tài)方法
默認(rèn)方法:使用 default 修飾,不可省略,供子類調(diào)用或者子類重寫。
靜態(tài)方法:使用 static 修飾,供接口直接調(diào)用。靜態(tài)與.class 文件相關(guān),只能使用接口名調(diào)用,不可以通過實(shí)現(xiàn)類的類名或者實(shí)現(xiàn)類的對象調(diào)用
*/
public interface InterFaceName {
  public default void method() {
    // 執(zhí)行語句
  }
 public static void method2() {
  // 執(zhí)行語句
 }
}

/*含有私有方法和私有靜態(tài)方法
私有方法:使用 private 修飾,供接口中的默認(rèn)方法或者靜態(tài)方法調(diào)用。*/
public interface InterFaceName {
  private void method() {
    // 執(zhí)行語句
  }
}
  • 基本實(shí)現(xiàn)
    類與接口的關(guān)系為實(shí)現(xiàn)關(guān)系,即類實(shí)現(xiàn)接口,該類可以稱為接口的實(shí)現(xiàn)類,也可以稱為接口的子類。實(shí)現(xiàn)的動(dòng)作類似繼承,格式相仿,只是關(guān)鍵字不同,實(shí)現(xiàn)使用 implements 關(guān)鍵字。
    非抽象子類實(shí)現(xiàn)接口:
  1. 必須重寫接口中所有抽象方法。
  2. 繼承了接口的默認(rèn)方法,即可以直接調(diào)用,也可以重寫。但是只能通過實(shí)現(xiàn)類的對象來調(diào)用
    實(shí)現(xiàn)格式:
class 類名 implements 接口名 {
  // 重寫接口中抽象方法【必須】
  // 重寫接口中默認(rèn)方法【可選】
}

Tips:

類的靜態(tài)變量和靜態(tài)方法能否被子類繼承?
結(jié)論:java中靜態(tài)屬性和靜態(tài)方法可以被繼承,但是沒有被重寫(overwrite)而是被隱藏.
原因:
1). 靜態(tài)方法和屬性是屬于類的,調(diào)用的時(shí)候直接通過類名.方法名完成對,不需要繼承機(jī)制及可以調(diào)用。如果子類里面定義了靜態(tài)方法和屬性,那么這時(shí)候父類的靜態(tài)方法或?qū)傩苑Q之為"隱藏"。如果你想要調(diào)用父類的靜態(tài)方法和屬性,直接通過父類名.方法或變量名完成,至于是否繼承一說,子類是有繼承靜態(tài)方法和屬性,但是跟實(shí)例方法和屬性不太一樣,存在"隱藏"的這種情況。
2). 多態(tài)之所以能夠?qū)崿F(xiàn)依賴于繼承、接口和重寫、重載(繼承和重寫最為關(guān)鍵)。有了繼承和重寫就可以實(shí)現(xiàn)父類的引用指向不同子類的對象。重寫的功能是:"重寫"后子類的優(yōu)先級要高于父類的優(yōu)先級,但是“隱藏”是沒有這個(gè)優(yōu)先級之分的。
3). 靜態(tài)屬性、靜態(tài)方法和非靜態(tài)的屬性都可以被繼承和隱藏而不能被重寫,因此不能實(shí)現(xiàn)多態(tài),不能實(shí)現(xiàn)父類的引用可以指向不同子類的對象。非靜態(tài)方法可以被繼承和重寫,因此可以實(shí)現(xiàn)多態(tài)。

package com.study.test;
 
public class A { //父類
    public static String staticStr = "A靜態(tài)屬性";
    public String nonStaticStr = "A非靜態(tài)屬性";
    public static void staticMethod(){
        System.out.println("A靜態(tài)方法");
    }
    public void nonStaticMethod(){
        System.out.println("A非靜態(tài)方法");
    }
}

package com.study.test;
 
public class B extends A{//子類B
    public static String staticStr = "B改寫后的靜態(tài)屬性";
    public String nonStaticStr = "B改寫后的非靜態(tài)屬性";
    public static void staticMethod(){
        System.out.println("B改寫后的靜態(tài)方法");
    }
}

package com.study.test;
 
public class C extends A{//子類C繼承A中的所有屬性和方法
 
}

package com.study.test;
 
public class StaticExtendsTest {
 
    public static void main(String[] args) {
        C c = new C();
        System.out.println(c.nonStaticStr);
        System.out.println(c.staticStr);
        c.staticMethod();//輸出的結(jié)果都是父類中的非靜態(tài)屬性、靜態(tài)屬性和靜態(tài)方法,推出靜態(tài)屬性和靜態(tài)方法可以被繼承
        
        System.out.println("-------------------------------");
        
        A c1 = new C();
        System.out.println(c1.nonStaticStr);
        System.out.println(c1.staticStr);
        c1.staticMethod();//結(jié)果同上,輸出的結(jié)果都是父類中的非靜態(tài)屬性、靜態(tài)屬性和靜態(tài)方法,推出靜態(tài)屬性和靜態(tài)方法可以被繼承
    
        System.out.println("-------------------------------");
        B b = new B();
        System.out.println(b.nonStaticStr);
        System.out.println(b.staticStr);
        b.staticMethod();
        
        System.out.println("-------------------------------");
        A b1 = new B();
        System.out.println(b1.nonStaticStr);
        System.out.println(b1.staticStr);
        b1.staticMethod();//結(jié)果都是父類的靜態(tài)方法,說明靜態(tài)方法不可以被重寫,不能實(shí)現(xiàn)多態(tài)
    }
 
}

測試結(jié)果如下:

A非靜態(tài)屬性
A靜態(tài)屬性
A靜態(tài)方法
-------------------------------
A非靜態(tài)屬性
A靜態(tài)屬性
A靜態(tài)方法
-------------------------------
B改寫后的非靜態(tài)屬性
B改寫后的靜態(tài)屬性
B改寫后的靜態(tài)方法
-------------------------------
A非靜態(tài)屬性
A靜態(tài)屬性
A靜態(tài)方法
  • 接口的多實(shí)現(xiàn)
    之前學(xué)過,在繼承體系中,一個(gè)類只能繼承一個(gè)父類。而對于接口而言,一個(gè)類是可以實(shí)現(xiàn)多個(gè)接口的,這叫做接口的多實(shí)現(xiàn)。并且,一個(gè)類能繼承一個(gè)父類,同時(shí)實(shí)現(xiàn)多個(gè)接口。
class 類名 [extends 父類名] implements 接口名1,接口名2,接口名3... {
 // 重寫接口中抽象方法【必須】
 // 重寫接口中默認(rèn)方法【不重名時(shí)可選】
}

接口中,有多個(gè)抽象方法時(shí),實(shí)現(xiàn)類必須重寫所有抽象方法。如果抽象方法有重名的,只需要重寫一次.
接口中,有多個(gè)默認(rèn)方法時(shí),實(shí)現(xiàn)類都可繼承使用。如果默認(rèn)方法有重名的,必須重寫一次
接口中,存在同名的靜態(tài)方法并不會(huì)沖突,原因是只能通過各自接口名訪問靜態(tài)方法。

  • 接口的多繼承
    一個(gè)接口能繼承另一個(gè)或者多個(gè)接口,這和類之間的繼承比較相似。接口的繼承使用 extends 關(guān)鍵字,子接口繼承父接口的方法。如果父接口中的默認(rèn)方法有重名的,那么子接口需要重寫一次

小貼士:
子接口重寫默認(rèn)方法時(shí),default關(guān)鍵字可以保留。
子類重寫默認(rèn)方法時(shí),default關(guān)鍵字不可以保留。

接口中,無法定義成員變量,但是可以定義常量,其值不可以改變,默認(rèn)使用public static final修飾。
接口中,沒有構(gòu)造方法,不能創(chuàng)建對象。
接口中,沒有靜態(tài)代碼塊。

多態(tài)

多態(tài)是繼封裝、繼承之后,面向?qū)ο蟮牡谌筇匦?/p>

父類類型 變量名 = new 子類對象;
變量名.方法名();
Fu f = new Zi();
f.method();  //多態(tài)規(guī)定,執(zhí)行的是子類重寫的方法
  • 多態(tài)的轉(zhuǎn)型分為向上轉(zhuǎn)型與向下轉(zhuǎn)型兩種:
    向上轉(zhuǎn)型
    向上轉(zhuǎn)型:多態(tài)本身是子類類型向父類類型向上轉(zhuǎn)換的過程,這個(gè)過程是默認(rèn)的。
    當(dāng)父類引用指向一個(gè)子類對象時(shí),便是向上轉(zhuǎn)型。
    使用格式:
父類類型 變量名 = new 子類類型();
如:Animal a = new Cat();

向下轉(zhuǎn)型
向下轉(zhuǎn)型:父類類型向子類類型向下轉(zhuǎn)換的過程,這個(gè)過程是強(qiáng)制的。
使用格式:

子類類型 變量名 = (子類類型) 父類變量名;
如:Cat c =(Cat) a;

當(dāng)使用多態(tài)方式調(diào)用方法時(shí),首先檢查父類中是否有該方法,如果沒有,則編譯錯(cuò)誤。也就是說,不能調(diào)用子類擁有,而父類沒有的方法。編譯都錯(cuò)誤,更別說運(yùn)行了。這也是多態(tài)給我們帶來的一點(diǎn)"小麻煩"。所以,想要調(diào)用子類特有的方法,必須做向下轉(zhuǎn)型。
轉(zhuǎn)型的異常
轉(zhuǎn)型的過程中,一不小心就會(huì)遇到這樣的問題,請看如下代碼:

public class Test {
  public static void main(String[] args) {
    // 向上轉(zhuǎn)型
    Animal a = new Cat();
    a.eat(); // 調(diào)用的是 Cat 的 eat
    // 向下轉(zhuǎn)型
    Dog d = (Dog)a;
    d.watchHouse(); // 調(diào)用的是 Dog 的 watchHouse 【運(yùn)行報(bào)錯(cuò)】
  }
}

為了避免ClassCastException的發(fā)生,Java提供了 instanceof 關(guān)鍵字,給引用變量做類型的校驗(yàn),格式如下:
變量名 instanceof 數(shù)據(jù)類型
如果變量屬于該數(shù)據(jù)類型,返回true。
如果變量不屬于該數(shù)據(jù)類型,返回false。

public class Test {
public static void main(String[] args) {
// 向上轉(zhuǎn)型
Animal a = new Cat();
a.eat(); // 調(diào)用的是 Cat 的 eat
// 向下轉(zhuǎn)型
if (a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse(); // 調(diào)用的是 Cat 的 catchMouse
} else if (a instanceof Dog){
Dog d = (Dog)a;
d.watchHouse(); // 調(diào)用的是 Dog 的 watchHouse
}
}
}

final關(guān)鍵字

final: 不可改變。可以用于修飾類、方法和變量。
類:被修飾的類,不能被繼承。
方法:被修飾的方法,不能被重寫。
變量:被修飾的變量,不能被重新賦值。

  • 修飾類
    查詢API發(fā)現(xiàn)像 public final class String 、 public final class Math 、 public final class Scanner等,很多我們學(xué)習(xí)過的類,都是被final修飾的,目的就是供我們使用,而不讓我們所以改變其內(nèi)容。
  • 修飾方法
修飾符 final 返回值類型 方法名(參數(shù)列表){
  //方法體
}

重寫被 final 修飾的方法,編譯時(shí)就會(huì)報(bào)錯(cuò)。

  • 修飾變量
    1、局部變量——基本類型
    基本類型的局部變量,被final修飾后,只能賦值一次,不能再更改。
public class FinalDemo1 {
public static void main(String[] args) {
// 聲明變量,使用final修飾
final int a;
// 第一次賦值
a = 10;
// 第二次賦值
a = 20; // 報(bào)錯(cuò),不可重新賦值
// 聲明變量,直接賦值,使用final修飾
final int b = 10;
// 第二次賦值
b = 20; // 報(bào)錯(cuò),不可重新賦值
}
}
  1. 局部變量——引用類型
    引用類型的局部變量,被final修飾后,只能指向一個(gè)對象,地址不能再更改。但是不影響對象內(nèi)部的成員變量值的修改
public class FinalDemo2 {
public static void main(String[] args) {
// 創(chuàng)建 User 對象
final User u = new User();
// 創(chuàng)建 另一個(gè) User對象
u = new User(); // 報(bào)錯(cuò),指向了新的對象,地址值改變。
// 調(diào)用setName方法
u.setName("張三"); // 可以修改
}
}
  1. 成員變量
    成員變量涉及到初始化的問題,初始化方式有兩種,只能二選一
    被final修飾的常量名稱,一般都有書寫規(guī)范,所有字母都大寫。
    顯示初始化:
public class User {
  final String USERNAME = "張三";
  private int age;
}

構(gòu)造方法初始化:

public class User {
  final String USERNAME ;
  private int age;
  public User(String username, int age) {
    this.USERNAME = username;
   this.age = age;
  }
}

權(quán)限修飾符

public protected default(空的) private
同一類中
同一包中(子類與無關(guān)類)
不同包的子類
不同包中的無關(guān)類

編寫代碼時(shí),如果沒有特殊的考慮,建議這樣使用權(quán)限:
成員變量使用 private ,隱藏細(xì)節(jié)。
構(gòu)造方法使用 public ,方便創(chuàng)建對象。
成員方法使用 public ,方便調(diào)用方法。
小貼士:不加權(quán)限修飾符,其訪問能力與default修飾符相同

內(nèi)部類

成員內(nèi)部類
成員內(nèi)部類 :定義在類中方法外的類。

class 外部類 {
  class 內(nèi)部類{
  }
}

訪問特點(diǎn)
內(nèi)部類可以直接訪問外部類的成員,包括私有成員。
外部類要訪問內(nèi)部類的成員,必須要建立內(nèi)部類的對象。
創(chuàng)建內(nèi)部類對象格式:
外部類名.內(nèi)部類名 對象名 = new 外部類型().new 內(nèi)部類型();

public class Person {
private boolean live = true;
class Heart {
public void jump() {
// 直接訪問外部類成員
if (live) {
System.out.println("心臟在跳動(dòng)");
} else {
System.out.println("心臟不跳了");
}
}
}
 public boolean isLive() {
return live;
} 
public void setLive(boolean live) {
this.live = live;
}
}

public class InnerDemo {
public static void main(String[] args) {
// 創(chuàng)建外部類對象
Person p = new Person();
// 創(chuàng)建內(nèi)部類對象
Heart heart = p.new Heart();
// 調(diào)用內(nèi)部類方法
heart.jump();
// 調(diào)用外部類方法
p.setLive(false);
// 調(diào)用內(nèi)部類方法
heart.jump();
}
} 
輸出結(jié)果:
心臟在跳動(dòng)
心臟不跳了
  • 匿名內(nèi)部類對象
    匿名內(nèi)部類 :是內(nèi)部類的簡化寫法。它的本質(zhì)是一個(gè) 帶具體實(shí)現(xiàn)的 父類或者父接口的 匿名的 子類對象。
    格式:
new 父類名或者接口名(){
  // 方法重寫
  @Override
  public void method() {
    // 執(zhí)行語句
  }
};

public abstract class FlyAble{
  public abstract void fly();
}

public class InnerDemo {
  public static void main(String[] args) {
  /*
  1.等號右邊:是匿名內(nèi)部類,定義并創(chuàng)建該接口的子類對象
  2.等號左邊:是多態(tài)賦值,接口類型引用指向子類對象
  */
  FlyAble f = new FlyAble(){
    public void fly() {
      System.out.println("我飛了~~~");
    }
  };

  //調(diào)用 fly方法,執(zhí)行重寫后的方法
  f.fly();
  }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,527評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,687評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,640評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,957評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,682評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,011評論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,009評論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,183評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,714評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,435評論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,665評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,148評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,838評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,251評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,588評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,379評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,627評論 2 380

推薦閱讀更多精彩內(nèi)容