繼承:爲了實現複用;繼承可以使用 extends 和 implements 這兩個關鍵字來實現繼承,而且所有的類 都是繼承於 java.lang.Object,當一個類沒有繼承的兩個關鍵字,則默認繼承object(這個類在 java.lang 包中,所以不需要 import)祖先類。
//在 Java 中,類的繼承是單一繼承,也就是說,一個子類只能擁有一個父類,所以 extends 只能繼承一個類。
//使用 implements 關鍵字可以變相的使java具有多繼承的特性,
// 使用範圍爲類繼承接口的情況,可以同時繼承多個接口(接口跟接口之間採用逗號分隔)。
封裝:爲了隱藏實現細節,對外只暴露接口,提供公共的訪問方式;
多態:滿足繼承關係,父類引用變量指向子類對象,子類重寫父類方法;消除類型之間的耦合關係。
類:一種抽象的數據類型;具備某些共同特徵的實體的集合;是對所具有的相同特徵實體的抽象。
定義了私有變量和方法。
類--【實例化】--對象;所以對象又稱爲實例。對象--【抽象】--類;
類描述的是對象的共同特徵,比如身高,必須體現創建對象,通過對象去訪問這個特徵。
一個類主要描述的是狀態(身高、體重、顏色,一個類的屬性)和動作(吃,跳舞,一個類的方法)。
private:只能在當前類內部訪問 protected:能在當前類和子類,同一個包中訪問; public:能在當前類/子類/其他package中訪問。
面向接口編程:開發功能的時候先定義接口,接口中定義約定好的功能方法聲明,通過實現該接口
進行功能實現。
angular css文件webpack打包原理:每一個component的HTML文件的每一個標籤,都會被唯一的屬性所標識,在渲染的時候,會通過
類選擇器(或其他選擇器)+ 屬性標識被選擇添加相應的樣式。
angular 屬性裝飾器如@Input,
@Compont({
html;
css;
})
class UserComponent{
@Input() username;//UserComponent.prototype.ng....=xxxx-[username]
ngOnInit(){
}
}
//parent
<app-user [username]="'xiaodong'"></app-user>
Object.getOwnProperties() && UserComponent.prototype.ng....=xxxx-[username]
let controller=new UserComponent();
controller.username=xiaodong
子組件會給自己的類的原型上打上標籤,父組件在使用子組件,構建標籤的時候,會通過user
如子組件有一個@Input() name;父組件class UserComponent{}
屬性裝飾器接收兩個參數(target,key),其實在父組件中,user會被打上標識,user.prototype.ng****;
子組件會通過該裝飾器去找,發現有一個標識中有name屬性,就傳過來該值。
//調用的方法與被調用的方法在同一個類中,類名.可以省略不寫。 public class MethodTest06 { public static void main(String[] args){ // MethodTest06.m(); // 找的是當前類中的方法 // m(); A.doOther(); // doOther(); 直接調用其他類中的方法,編譯報錯。 } public static void m(){ System.out.println("m方法執行了"); } } class A{ public static void doOther(){ System.out.println("A類中的方法執行了"); } }
public class MethodTest11 { public static void main(String[] args) { // 方法在執行過程中,在JVM中的內存是如何分配的,內存是如何變化? // 方法只定義,不調用,是不會執行的,並且在JVM也不會分配運行所屬的內存空間呢 // JVM中有三塊主要內存空間: // 方法取內存。堆。棧 } }
public class OverloadTest03 { public static void main(String[] args) { // 1.方法重載又被稱爲:overload // 2.功能相似的時候,儘可能讓方法名想同。 // 3.什麼條件滿足之後 構成了方法重載? // 同一個類中,方法名想同,參數列表不同,數量不同。 // 方法重載的具體應用 System.out.println("hello world"); } } class U{ }
//子類是不繼承父類的構造器(構造方法或者構造函數)的,它只是調用(隱式或顯式)。 // 如果父類的構造器帶有參數,則必須在子類的構造器中顯式地通過 super 關鍵字調用父類的構造器並配以適當的參數列表。 //如果父類構造器沒有參數,則在子類的構造器中不需要使用 super 關鍵字調用父類構造器,系統會自動調用父類的無參構造器。 public class SuperClass { private int n; SuperClass(){ System.out.println("SuperClass"); } SuperClass(int n){ System.out.println("SuperClass(int n)"); System.out.println("我是小傻子"); } } class SubClass extends SuperClass{ private int n; // 自動調用父類的無參構造器 SubClass(){ System.out.println("SubClass()"); } SubClass(int n){ // 調用父類的有參構造器 super(300); System.out.println("SubClass(int n)"); } } class TestSuperSub{ public static void main(String[] args){ SubClass s1 = new SubClass(); SubClass s2 = new SubClass(100); } }
public class OOTest01 { public static void main(String[] args) { // 通過一個類可以實例化N個對象 // 實例化對象的語法:new 類名() // new運算符的作用是創建對象,在JVM堆內存中開闢新的內存空間。 // 方法區內存:在類加載的時候,class字節碼代碼片段被加載到該內存空間中 // 棧內存(局部變量):方法代碼片段執行的時候,會給該方法分配內存空間,在棧內存中壓棧。 // 堆內存:new的對象在堆內存中 // Student是一個引用數據類型; // s是一個變量名;是一個局部變量,在棧內存中存儲; // new Student()是一個學生對象;new運算符在堆內存中開闢的內存空間稱爲對象。 // 引用是一個變量,只不過這個變量中保存了另一個java對象的內存地址。 // 無法直接操控堆內存,java中沒有指針,只能通過引用去訪問堆內存當中的對象內部的實例變量。 Student s = new Student(); s.address = "beijing"; s.sex = true; s.age = 10; System.out.println(s.sex); System.out.println(s.address); System.out.println(s.age); System.out.println(s.name); System.out.println(s.no); /* * 通過類實例化一個全新的對象 * stu是一個引用;是一個局部變量;Student是變量的數據類型; * 局部變量在棧內存中存儲; * 成員變量中的實例變量在堆內存的java對象內部存儲; * 實例變量是一個對象一份,100個對象有100份; * no是實例變量,是對象級別的變量,變量存儲在java對象的內部,必須先有對象,通過對象才能訪問no這個實例變量, * 不能直接通過類名.no; * */ Student stu = new Student(); } }
public class OOTest06 { public static void main(String[] args) { Student stu = new Student(); // String brand, String labelStyle, String color, Student stu Computer computer = new Computer("apple", "ss","blue",stu); // 實例變量必須先創建對象。 // stu是引用變量,是局部變量,變量中保存內存地址指向堆內存當中的Student對象。 // 訪問實例變量的語法,引用.變量名。computer.color,color是實例變量 // 讀取,修改computer.color="blue" // stu.computer.color = "blue"; stu.name = "張三"; stu.computer = computer; System.out.println(stu.name + "的筆記本是" + computer.brand); } }
//面向過程關注的是因果關係。 //Student是引用數據類型 //局部變量在棧內存 //靜態變量在方法區內存 public class Student { int no; String name; boolean sex; int age; String address; Computer computer; }
import address.Address; public class User { /*no,name,addr是一個實例變量 * int是基本數據類型; * String是引用數據類型;Address是引用數據類型; * address是一個引用;name是一個引用 * 不可變數據結構*/ int no; private String name; private Address address = null; public void setAddress(Address address) { this.address = address; } public Address getAddress() { return address; } public User(int no, String name) { this.no = no; this.name = name; } void bar() { } }
package aboutThis; /* * 關於this: * this是一個關鍵字,翻譯爲:這個 * this是一個引用,this是一個變量,this變量中保存了內存地址指向了自身。this存儲在JVM堆內存java對象內部。 * 創建100個Java對象,每一個對象都有一個this,也就說有100個不同的this。 * * 沒有static關鍵字修飾的方法稱爲實例方法。訪問?引用. * 有static。類名.Customer.doSome * 沒有static關鍵字修飾的變量稱爲實例變量。 * 當一個行爲、動作執行的過程中,是需要對象參與的,name這個方法一定要定義爲實例方法。不需要static關鍵字修飾 * this可以出現在實例方法中,this指向當前動作的對象。 * this在多數情況下是可以省略不寫的。 * this不能使用在static修飾的方法中。 * * this可以使用在實例方法當中,代表當前對象 * 可以使用在構造函數中,通過當前的構造方法調用其他的構造方法【this(實參)】 * */ public class Customer { // 【name:堆內存的對象內部中存儲,所以訪問該數據的時候,會先創建對象,】 String name; // 沒有被static修飾,因此是實例變量,需要通過引用.的方式訪問。 public Customer(){ } // 每一個顧客的行爲不一樣,屬於對象級別的行爲 // 以下方法定義爲實例方法,因爲每一個顧客在真正購物的時候,最終的結果是不同的。所以這個動作在完成時必須有對象的參與。 public void shopping(){ System.out.println(this.name+"在購物"); } //執行過程中沒有“當前對象”,因爲帶有static的方法是通過類名的方式訪問的。 // 或者上下文中沒有當前對象。自然不存在this(this代表的是當前正在執行這個動作的對象) public static void doSome(){ // doSome方法調用不是對象去調用,而是類名去調用,執行過程中沒有當前對象。 // name是一個實例變量,下面含義是訪問當前對象的name // static方法的調用不需要對象,直接使用類名 // 創建對象 Customer c = new Customer(); System.out.println(c.name); //此時name使用引用的方式訪問,訪問的是c引用指向對象的name } }
//git reset --soft HEAD^ //git stash list 查看stash列表 //git stash save '保存暫存區的更改' //git stash apply stash@{0} 應用暫存的更改i //git stash show -p stash@{0} 查看暫存區的某個更改 //git stash drop stash@{0} 從暫存區刪除
package duotai; /* * 概念: * 向上轉型:子類型-父類型;自動類型轉換。 * 向下轉型:父類型-子類型:強制類型轉換。 * 上述兩種方式的存在,要求必須是父子繼承關係。*/ public class Test { public static void main(String[] args) { // new Cat()創建的對象類型是cat,a2這個引用的數據類型是Animal,他們之間進行了類型轉換。 Animal a2 = new Dog(); // java分編譯和運行階段 // 先編譯後運行, // 編譯階段,檢查a2這個引用的數據類型爲Animal,Animal.class這個字節碼當中有move()方法,編譯通過。這個過程爲 // 靜態綁定,編一階段綁定。只有靜態綁定成功之後,纔有後續運行。 // 運行階段:JVM內存當中真實創建的對象爲Cat對象,以下程序在運行階段一定會調用Cat對象的move方法。此時發生了程序的 // 動態綁定。 // 無論cat是否重寫move方法,運行階段一定調用Cat對象的move方法,因爲底層真是對象就是Cat對象。 a2.move(); // 編譯階段,檢查a2這個引用的數據類型爲Animal;從Animal.class字節碼文件中找catchMouse方法,最終沒有找到 // 導致靜態綁定失敗,即編譯失敗 // a2.catchMouse(); // 想要實現上述方法,需要強制類型轉換,將Animal轉換爲Cat // 當調用的方法是子類型特有的額,其父類型不存在,需要轉換 Dog c2 = (Dog)a2; c2.catchMouse(); Animal a3 = new Bird(); // Cat c3 = (Cat)a3; // c3.catchMouse(); if(a3 instanceof Dog){ Dog c3 = (Dog)a3; c3.catchMouse(); } else if(a3 instanceof Bird){ Bird b3 = (Bird)a3; } } }
package overload; //什麼是方法重載:在同一個類中,方法完成的功能是相似的。建議方法名相同,就像在調用同一個方法。 //什麼條件滿足之後,g構成方法重載:在同一個類中,方法名相同,參數列表不同。 //方法重載和什麼無關:方法的返回值類型,方法的修飾符列表 //方法覆蓋(方法重寫) //當父類方法無法滿足當前業務需求的時候,需要重新寫父類的方法。 //方法重寫發生在具有繼承關係的父子類之間。,返回值類型相同,方法名相同,形參列表相同。 //私有方法、構造方法不存在繼承,不能實現覆蓋 public class Test01 { public static void main(String[] args) { try { new Test01().run(1); } catch (Throwable e) { e.printStackTrace(); } } //exception //error public void run(int a) throws IllegalArgumentException { throw new IllegalArgumentException(); } }
package objectAnd; /* * 方法調用的時候,涉及到參數傳遞問題的時候,java只有一種語法機制,就是講變量中保存的只傳過去了, * 只不過有時這個值是字面值,有時這個值是另一個java對象的內存地址。*/ public class Test02 { public static void main(String[] args) { User u = new User(20); add(u); System.out.println("main"+ u.age); } public static void add(User u){ u.age++; System.out.println("add"+u.age); } } class User{ int age; // 實例變量 // 構造方法 public User(int i) { age = i; } }
package conMethod; /* * 構造方法的作用: * 1.創建對象; * 2.創建對象的同時,初始化實例變量的內存空間; * 成員變量之實例變量(對象變量),屬於對象級別的變量,必須先有對象,纔能有實例變量。 * 實例變量沒有手動賦值的時候,系統默認賦值在什麼時候完成? * 是在類加載的時候嗎?不是。因爲類加載的時候,只是加載了代碼片段,還沒來得及創建對象,此時實例變量沒有初始化。 * 實際上,實例變量的內存空間是在構造方法執行過程中完成開闢的,完成初始化的。*/ public class Test02 { public static void main(String[] args) { // 創建對象,給對象的屬性賦值 // Account act1 = new Account(); act1.setActno("no"); System.out.println(act1.getActno()); act1.setBalance(10.00); System.out.println(act1.getBalance()); Account act2 = new Account("有參數構造器"); System.out.println(act2.getActno()); } }