注:看此篇時強烈建議有必定的面向對象思想基礎,有必定的基礎後先翻到下面看第九條:9.面向對象: 從未封裝→封裝→繼承→多態→抽象類→接口的代碼演變,按這個邏輯去看,哪有不理解的再回頭看知識點,這是掌握理解最好最快的方法,切記切記javascript
描述一個物質均可以經過兩方面說明:數據模型(屬性)、行爲模型(行爲)。在Java編程中,咱們使用成員變量表示數據模型,用成員方法表示行爲模型。使用類表示某些具備相同屬性和行爲的事物。html
語法:java
[訪問修飾符] 類名(){ }編程
做用:ide
構造函數,通常是用於爲成員屬性賦初始化值;函數
注意:this
- 當類中沒有顯式的構造方法,實例化該類的對象時,程序會自動建立一個公開的無參構造方法;
- 若是類中有顯示的構造方法,程序就不會建立無參構造;
- static關鍵字用來聲明獨立於對象的靜態方法。靜態方法不能使用類的非靜態變量。靜態方法從參數列表獲得數據,而後計算這些數據。
- 對類變量和方法的訪問能夠直接使用 classname.variablename 和 classname.methodname 的方式訪問。
以下例所示,static修飾符用來建立類方法和類變量:spa
public class InstanceCounter {
private static int numInstances = 0;
protected static int getCount() {
return numInstances;
}
private static void addInstance() {
numInstances++;
}
InstanceCounter() {
InstanceCounter.addInstance();
}
public static void main(String[] arguments) {
System.out.println("Starting with " +
InstanceCounter.getCount() + " instances");
for (int i = 0; i < 500; ++i){
new InstanceCounter();
}
System.out.println("Created " +
InstanceCounter.getCount() + " instances");
}
}
運行結果:線程
Starting with 0 instances
Created 500 instances
- 聲明在全部方法體和代碼塊以外,而且沒有使用static修飾的變量,叫作實例變量;
- 可使用訪問修飾符和final修飾;
- 使用final修飾時,必定要賦值;
- 實例變量是在對象被建立時建立,對象被銷燬時銷燬;
- 做用域範圍在整個類中;
- 聲明在構造方法、靜態方法、實例方法、代碼塊中的變量,都是局部變量;
- 不能使用static和訪問修飾符修飾;
- 可使用final修飾,即爲常量,沒必要在聲明語句中賦值;
- 當執行局部變量所在的方法或代碼塊時,纔有機會被建立,在方法或代碼塊執行結束後被自動銷燬;
- 局部變量在內存的棧區分配;
- 局部變量在使用以前必需要先賦值;
- 聲明在全部方法體和代碼塊以外,而且使用static修飾的變量;
- 可使用訪問修飾符修飾;
- 通常配合final使用,即public static fianl,標識符使用大寫;
- 類變量被分配在靜態存儲區,是被全部該類的對象共享數據;
- 類變量是在程序開始時被建立,程序結束時銷燬;
Java中可使用訪問控制符來保護對類、變量、方法和構造方法的訪問。Java 支持 4 種不一樣的訪問權限。code
- default (即缺省,什麼也不寫): 在同一包內可見,不使用任何修飾符。使用對象:類、接口、變量、方法。
- private : 在同一類內可見。使用對象:變量、方法。 注意:不能修飾類(外部類)
- public : 對全部類可見。使用對象:類、接口、變量、方法
- protected : 對同一包內的類和全部子類可見。使用對象:變量、方法。 注意:不能修飾類(外部類)
咱們能夠經過如下表來講明訪問權限:
爲了實現一些其餘的功能,Java 也提供了許多非訪問修飾符。
- static 修飾符,用來修飾類方法和類變量。
- final 修飾符,用來修飾類、方法和變量,final 修飾的類不可以被繼承,修飾的方法不能被繼承類從新定義,修飾的變量爲常量,是不可修改的。
final修飾變量:
- final 表示"最後的、最終的"含義,變量一旦賦值後,不能被從新賦值。被 final 修飾的實例變量必須顯式指定初始值。
- final 修飾符一般和 static 修飾符一塊兒使用來建立類常量。
//實例
public class Test{
final int value = 10;
// 下面是聲明常量的實例
public static final int BOXWIDTH = 6;
static final String TITLE = "Manager";
public void changeValue(){
value = 12; //將輸出一個錯誤
}
}
final修飾方法:
- 類中的 final 方法能夠被子類繼承,可是不能被子類修改。
- 聲明 final 方法的主要目的是防止該方法的內容被修改。
以下所示,使用 final 修飾符聲明方法:
public class Test{
public final void changeName(){
// 方法體
}
}
final修飾類:
- final 類不能被繼承,沒有類可以繼承 final 類的任何特性。
//實例
public final class Test {
// 類體
}
注意:
- 當final修飾類時,當前類不能被繼承;
- 當final修飾方法時,該方法不能被重寫;
- 當final修飾變量時,變量的值不能被修改,即爲常量;
abstract修飾符,用來建立抽象類和抽象方法。
抽象類:
- 抽象類不能用來實例化對象,聲明抽象類的惟一目的是爲了未來對該類進行擴充。
- 一個類不能同時被 abstract 和 final 修飾。若是一個類包含抽象方法,那麼該類必定要聲明爲抽象類,不然將出現編譯錯誤。
- 抽象類能夠包含抽象方法和非抽象方法。
規則:
- 含有抽象方法的類,必定是抽象類;
- 抽象類中能夠聲明成員變量、常量、成員方法、抽象方法,抽象類中不必定要有抽象方法;
- 抽象類不能被實例化;
- 抽象類能夠被繼承;
- 能夠經過兩種方式得到抽象類對象:父類引用指向子類對象、匿名內部類;
- 子類必須重寫抽象父類的全部抽象方法,或者是把子類也定義爲抽象類;
- 若是一個類繼承的抽象父類還有上級抽象父類,那麼子類中須要要重寫全部抽象父類的全部抽象方法;
- 抽象類也能夠繼承非抽象類,同時繼承了父類的全部非私有的屬性和方法;
實例:
abstract class Caravan{
private double price;
private String model;
private String year;
public abstract void goFast(); //抽象方法
public abstract void changeColor();
}
抽象方法
- 抽象方法是一種沒有任何實現的方法,該方法的的具體實現由子類提供。
- 抽象方法不能被聲明成 final 和 static。
- 任何繼承抽象類的子類必須實現父類的全部抽象方法,除非該子類也是抽象類。
- 若是一個類包含若干個抽象方法,那麼該類必須聲明爲抽象類。抽象類能夠不包含抽象方法。
*抽象方法的聲明以分號結尾,例如:public abstract sample();
實例:
public abstract class SuperClass{
abstract void m(); //抽象方法
}
class SubClass extends SuperClass{
//實現抽象方法
void m(){
.........
}
}
synchronized 和 volatile 修飾符,主要用於線程的編程。
synchronized 修飾符
synchronized 關鍵字聲明的方法同一時間只能被一個線程訪問。synchronized 修飾符能夠應用於四個訪問修飾符。
實例
public synchronized void showDetails(){
.......
}
transient 修飾符
- 序列化的對象包含被 transient 修飾的實例變量時,java 虛擬機(JVM)跳過該特定的變量。
- 該修飾符包含在定義變量的語句中,用來預處理類和變量的數據類型。
實例
public transient int limit = 55; // 不會持久化
public int b; // 持久化
**volatile **修飾符
- volatile 修飾的成員變量在每次被線程訪問時,都強制從共享內存中從新讀取該成員變量的值。並且,當成員變量發生變化時,會強制線程將變化值回寫到共享內存。這樣在任什麼時候刻,兩個不一樣的線程老是看到某個成員變量的同一個值。
- 一個 volatile 對象引用多是 null。
實例
public class MyRunnable implements Runnable
{
private volatile boolean active;
public void run()
{
active = true;
while (active) // 第一行
{
// 代碼
}
}
public void stop()
{
active = false; // 第二行
}
}
一般狀況下,在一個線程調用 run() 方法(在 Runnable 開啓的線程),在另外一個線程調用 stop() 方法。 若是 第一行 中緩衝區的 active 值被使用,那麼在 第二行 的 active 值爲 false 時循環不會中止。可是以上代碼中咱們使用了 volatile 修飾 active,因此該循環會中止。
this指當前對象,用法:
- 當局部變量名和實例變量名同名時,使用this.變量名來表示實例變量;
- this()表示當前類的構造方法,只能在構造方法中使用該寫法,而且是寫在構造方法內的第一行。
私有的屬性,公開的方法。
封裝的步驟:
- 聲明私有(private)的屬性;
- 聲明公開(public)的geter和seter方法;
Java中的繼承是單繼承,能夠實現多層繼承,繼承的關鍵字extends
語法:
public class Son extends Father{
}
規則:
- 子類繼承父類非私有的全部屬性和方法,不能繼承父類的構造方法;
- 實例化子類對象的步驟:先執行父類的構造方法,再執行子類的構造方法;
重寫定義:
- 子類從新聲明從父類繼承來的方法,稱爲方法重寫;
- 方法重寫時,方法的聲明部分要和父類保持一致(返回值類型,方法名,參數);
- 重寫方法的訪問權限要大於等於父類中方法的訪問權限;
- 子類重寫父類方法,子類對象調用的是子類中重寫後的方法;
- 使用static修飾的方法不能被重寫,可是能夠被子類重寫聲明;
- 不一樣包的子類能夠重寫父類中protected修飾的方法,可是不能以繼承的形式,用子類對象直接調用父類的該方法;
實現的必要條件:
- 繼承
- 重寫
- 父類引用指向子類對象
instanceof關鍵字:
語法:
if (對象名 instanceof 類名) {
類型轉換代碼;
}
實例:
Animal cat = new Cat();
if (cat instanceof Cat) {//返回結果爲boolean類型
Cat c = (Cat) cat;
c.eat();
}else{
System.out.println("類型不匹配");
}
語法:
public interface ITest {
}
規則:
- 接口使用interface關鍵字修飾;
- 接口是一個徹底抽象的抽象類;
- 接口中沒有構造方法;
- 接口不能被實例化對象;
- 接口中能夠聲明靜態常量、抽象方法、靜態方法;
- 接口中不能聲明實例方法,聲明抽象方法時,不能使用static關鍵字修飾;
- 聲明接口語句中,默認含有abstract關鍵字,抽象方法中也默認含有abstract關鍵字;
- 接口能夠被實現,使用implements關鍵字,一個類實現一個接口,必須重寫該接口中全部的抽象方法;
- 一個類能夠實現多個接口,每一個接口名用英文的逗號隔開,該類中必須重寫全部已實現接口中的抽象方法;
- 接口能夠繼承接口,接口與接口間是多繼承關係,接口不能繼承類;
未封裝:
public class Person {
int age;//年齡
String name;//姓名
public void print()
{
System.out.println("age:"+this.age+" "+"name:"+this.name);
}
}
class Text{
public static void main(String[] args) {
Person person = new Person();//實例化對象
person.age = -100;//賦值
person.name = "張三";
person.print();//執行類中的方法
}
}
運行結果:<br>age:-100 name:張三
封裝:
public class Person {
private int age;//年齡
private String name;//姓名
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"age=" + this.age +
", name='" + this.name + '\'' +
'}';
}
}
class Text{
public static void main(String[] args) {
Person person = new Person();
person.setAge(20);
person.setName("張三"); ;
String s = person.toString();
System.out.println(s);
}
}
運行結果:
Person{age=20, name='張三'}
繼承
public class Office {
public void print(){
System.out.println("打印");
}
}
class Word extends Office {
@Override
public void print() {
System.out.println("Word打印");
}
}
class Test{
public static void main(String[] args) {
Word word = new Word();
word.print();
}
}
運行結果:
Word打印
一個Java源文件中能夠聲明多個class類,但只能有一個public修飾的類。
多態
public class Office {
public void print(){
System.out.println("打印");
}
}
class Word extends Office {
@Override
public void print() {
System.out.println("Word打印");
}
}
class Excle extends Office{
@Override
public void print() {
System.out.println("Excel打印");
}
}
class Ppt extends Office{
public void daYin() {//子類能夠重寫父類方法,也能夠本身定義方法
System.out.println("PPT打印");
}
}
class Test{
public static void main(String[] args) {
Office o = new Word();//多種形態,即多態
o.print();
}
}
運行結果:
Word打印
class Test{
public static void main(String[] args) {
Office o = new Excle();
o.print();
}
}
運行結果:
Excel打印
class Test{
public static void main(String[] args) {
Office o = new Ppt();
o.print();
}
}
運行結果:
打印
爲避免這種方法名稱多樣的狀況,用一種約束叫抽象類
public abstract class Office {
public abstract void print();
}
class Word extends Office {
@Override
public void print() {
System.out.println("Word打印");
}
}
class Excle extends Office{
@Override
public void print() {
System.out.println("Excel打印");
}
}
class Ppt extends Office{
@Override
public void print() {
System.out.println("PPT打印");
}
}
class Test{
public static void main(String[] args) {
Office o = new Ppt();//父類引用指向子類對象,子類重寫父類方法,父類引用調用子類重寫後的方法,執行的結果是子類重寫後的方法
o.print();
}
}
運行結果:
PPT打印
接口是徹底抽象的抽象類,而且能夠多實現
接口默認爲:
public class abstract interface Office {
public abstract void print();
}
---------------------------------------------------------
public interface Office {
void print();
}
class Word implements Office {
@Override
public void print() {
System.out.println("Word打印");
}
}
class Excle implements Office{
@Override
public void print() {
System.out.println("Excel打印");
}
}
class Ppt implements Office{
@Override
public void print() {
System.out.println("PPT打印");
}
}
class Test{
public static void main(String[] args) {
Office o = new Ppt();
o.print();
}
}
運行結果爲:
PPT打印
成員內部類
成員內部類聲明在類中,方法體、代碼塊以外。和成員變量、成員方法在同一級別。
語法:
public class Out {
//成員內部類
public class Inner{
}
}
實例化成員內部類:
//先實例化外部類
Out o = new Out();
//使用外部類對象,再實例化內部
Out.Inner inner = o.new Inner();
實例:
public class Out {
//成員變量
public int a = 1;
//成員內部類
public class Inner{
public int a = 2;
//內部類的成員方法
public void print(){
//執行內部類中的實例變量a
System.out.println(a);
//執行外部類的實例變量a
System.out.println(Out.this.a);
}
}
}
靜態內部類
聲明的位置參考成員內部類。
語法:
public class Out {
//靜態內部類
public static class Inner{
}
}
實例化靜態內部的對象:
Out.Inner inner = new Out.Inner();
實例:
public class Out {
public static int a = 1;
public int b = 3;
//靜態內部類
public static class Inner{
public static int a = 2;
public static void print(){
//執行靜態內部的靜態變量
System.out.println(a);
//執行外部類的靜態變量
System.out.println(Out.a);
//執行外部類的實例變量
Out o = new Out();
System.out.println(o.b);
}
}
}
局部內部類
聲明在方法體或代碼塊內,做用域範圍在方法體或代碼塊內。
語法:
public class Out {
public void method(){
//局部內部類
class Inner{
//局部內部類的成員方法
public void print(){
System.out.println("局部內部類");
}
}
//實例化局部內部類
Inner inner = new Inner();
inner.print();
}
}
執行局部內部類的方法:
Test類:
public static void main(String[] args) {
Out o = new Out();
o.method();
}
匿名內部類
- 聲明位置同局部內部類同樣,前提條件:必須繼承一個類或實現一個接口,匿名內部類的聲明和實例化對象是同時進行的;
- 通常使用於得到抽象類或接口對象;
語法:
父類名/接口名 對象名 = new 父類名/接口名(){
//匿名內部類成員
};
實例:
父類
public class Father {
}
匿名內部類:
public class Out {
public void method(){
//匿名內部類對象
Father f = new Father(){
};
}
}
這一篇對新手是不友好的,不過對一些只知其一;不知其二的或者想複習的朋友可能幫助更大。