單例模式 繼承 多型
阿新 • • 發佈:2018-12-18
單例模式有23種,但是她必須滿足 一個類產生一個例項。 單例模式有以下特點: (1)單例模式只有一個例項; (2)單例類必須建立自己的唯一例項; (3)單例類必須給所有其他物件提供這一例項; 懶漢式單例模式:
class MySinglecTon{
private static Object lock = new Object();
private static MySinglecTon singlecTon = null;
private MySinglecTon(){
System.out.println("MySinglecTon().init" );
}
public static MySinglecTon getSinglecTon() {//提供一個全域性訪問點
if (singlecTon == null) {
synchronized (lock) {
if (singlecTon == null) {
singlecTon = new MySinglecTon();
}
}
}
/*3、if(sigleTon == null) {//第一個執行緒獲取資源後
synchronized (lock) {//接著進行上鎖,如果第一個執行緒的地址沒有賦給第一個執行緒,人後第二個執行緒進來判斷資源為空也可以進來,但是執行不了
sigleTon = new MySigleTon();//至少執行2遍
}
}*/
/*2、synchronized (lock) {//第一個執行緒進來之後上鎖,
if(sigleTon == null) { //進來獲取資源後,如果將地址沒賦給第一個執行緒,那第二個執行緒無法進入,導致資源的浪費
sigleTon = new MySigleTon();
}
}*/
/*1、if(sigleTon == null) {//只適用於單執行緒
sigleTon = new MySigleTon();
}*/
return singlecTon;
}
public static void main(String[] args) {
MySinglecTon singlecTon = MySinglecTon.getSinglecTon();
System.out.println(singlecTon);
}
}
餓漢式單例模式:
class MySingleTon{
private static MySingleTon singleTon = new MySingleTon();
private MySingleTon(){
System.out.println("MySingleTon().init");
}
public static MySingleTon getSingleTon(){//提供一個全域性訪問點
return singleTon;
}
}
public class eh {
public static void main(String[] args) {
MySingleTon singleTon = MySingleTon.getSingleTon();
System.out.println(singleTon);
}
}
執行緒安全的單例模式: 執行緒安全 是否有競態條件,就是臨界區程式碼段,有程式碼段之後是否進行了原子性操作,原子性操作就是對其進行加鎖處理。 靜態內部類實現單例模式:
class MysingleTon2{
private MysingleTon2(){
}
private static class SingleTon{ //只有訪問靜態內部類的時候才會建立物件
public static MysingleTon2 a = new MysingleTon2();
}
public static MysingleTon2 getInstance(){
return SingleTon.a;
}
}
public class Demo3 {
public static void main(String[] args) {
MysingleTon2 Singleton2 = MysingleTon2.getInstance();
System.out.println(Singleton2 );
}
}
訪問修飾限定符: (public)基類的資料成員派生類的訪問許可權 繼承: 派生類繼承了基類出建構函式的所有屬性。 super(); 呼叫基類的建構函式 super.data 訪問基類的資料成員 super.fun(); 呼叫基類的成員方法
class Base{
protected int cf;
public Base(int cf){
System.out.println("Base,init()");
this.cf = cf;
}
static {
System.out.println("Base.static{}");
}
{
System.out.println("Base.instance{}");
}
}
class Derieve extends Base{
private int df;
public Derieve(int cd,int cg){
super(cd);
System.out.println("Derieve,init{}");
}
static {
System.out.println("Derieve.static{}");
}
{
System.out.println("Derieve.instance{}");
}
public void fun(int cd) {
System.out.println("Derieve.fun(int)");
}
}
過載(overload):函式名相同,函式列表不同 與返回值不同,同時在繼承關係上也可以構成過載。 重寫(override):也叫覆蓋 ,函式名相同 引數列表不同,返回值相同, 但在一定條件下可以不同 ,(遵守了協變型別)。
class Base{
protected int cf;
public Base(int cf){
System.out.println("Base,init()");
this.cf = cf;
}
public void fun(){
System.out.println("Base.fun()");
}
}
class Derieve extends Base{
private int df;
public Derieve(int cd,int cg){
super(cd);
System.out.println("Derieve,init{}");
}
public void fun(){
System.out.println("Derieve.fun()");
}
public void fun1(int cd) {
System.out.println("Derieve.fun1(int)");
}
}
派生類建構函式的初始化順序: 基類派生類靜態塊初始化 =》基類例項塊構造初始化=》派生類例項塊建構函式初始化
基類和派生類的賦值: 只能把派生類的值賦給基類(這也是多型的基礎) 動多型:
class Base{
protected int cf;
public Base(int cf){
System.out.println("Base,init()");
this.cf = cf;
}
public void fun(){
System.out.println("Base.fun()");
}
public void fun1(){
System.out.println("Base.fun1()");
}
}
class Derieve extends Base{
private int df;
public Derieve(int cd,int cg){
super(cd);
System.out.println("Derieve,init{}");
}
public void fun(){
System.out.println("Derieve.fun()");
}
public void fun1(){
System.out.println("Derieve.fun1()");
}
}
public class jc {
public static void main(String[] args) {
Base base = new Derieve(111,222);
base.fun1();//靜多型 編譯的時候
base.fun();//動多型 執行的時候
}
}
基類產生的物件存放在堆上的方法表,在其方法區有當前class類的地址,當基類引用了派生類的物件時,其地址會被派生來的地址所覆蓋,從而輸出的為派生類的方法。