歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C#與Java實例化對象時的差異

C#與Java實例化對象時的差異

日期:2017/3/1 9:48:29   编辑:Linux編程

先來看看一段Java代碼:

package example;

class Print {

public Print(String info) {
System.out.println("測試信息----" + info);
}
}

class BaseA {

private Print p = new Print("實例變量A");
private static Print p1 = new Print("靜態變量A");

static {
System.out.println("BaseA靜態塊");
}

public BaseA() {
System.out.println("BaseA構造方法");
}

public void Invoke() {
System.out.append("Invoke----BaseA");
}
}

class BaseB extends BaseA {

private Print p = new Print("實例變量B");
private static Print p1 = new Print("靜態變量B");

static {
System.out.println("BaseB靜態塊");
}

public BaseB() {
System.out.println("BaseB構造方法");
}

@Override
public void Invoke() {
System.out.append("Invoke----BaseB");
}
}

class BaseC extends BaseB {

private Print p = new Print("實例變量C");
private static Print p1 = new Print("靜態變量C");

static {
System.out.println("BaseC靜態塊");
}

public BaseC() {
System.out.println("BaseC構造方法");
}

@Override
public void Invoke() {
System.out.append("Invoke----BaseC");
}
}

public class Test {

public static void main(String[] args) {
BaseC bc = new BaseC();
bc.Invoke();
}
}

run:
測試信息----靜態變量A
BaseA靜態塊
測試信息----靜態變量B
BaseB靜態塊
測試信息----靜態變量C
BaseC靜態塊
測試信息----實例變量A
BaseA構造方法
測試信息----實例變量B
BaseB構造方法
測試信息----實例變量C
BaseC構造方法
Invoke----BaseC成功構建 (總時間: 0 秒)

由此可見:Java在實例化對象的時候有幾個規律

1、靜態的肯定在前面:靜態變量>靜態塊代碼

2、總是從最底層的類開始實例化,從父類開始把所有靜態的加載完,然後從父類開始把所有實例的東東加載完

執行順序:

1. 初始化ParentClass的靜態字段(按聲明順序)
2. 初始化ParentClass的靜態塊
3. 初始化ChildClass的靜態字段(按聲明順序)

4. 初始化ChildClass的靜態塊

5. 初始化ParentClass的實例字段(按聲明順序)
6. 初始化ParentClass的構造方法
7. 初始化ChildClass的實例字段(按聲明順序)

8. 初始化ChildClass的構造方法

再來看看C#的代碼:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
class Print
{
public Print(string info)
{
Console.WriteLine("測試信息---" + info);
}
}

class BaseA
{
private Print p = new Print("實例變量A");
private static Print p1 = new Print("靜態變量A");

static BaseA()
{
Console.WriteLine("靜態構造方法A");
}

public BaseA()
{
Console.WriteLine("構造方法A");
}

public virtual void Invoke()
{
Console.WriteLine("Invoke---BaseA");
}
}

class BaseB : BaseA
{
private Print p = new Print("實例變量B");
private static Print p1 = new Print("靜態變量B");

static BaseB()
{
Console.WriteLine("靜態構造方法B");
}

public BaseB()
{
Console.WriteLine("構造方法B");
}
public override void Invoke()
{
Console.WriteLine("Invoke---BaseB");
}
}

class BaseC : BaseB
{
private Print p = new Print("實例變量C");
private static Print p1 = new Print("靜態變量C");

static BaseC()
{
Console.WriteLine("靜態構造方法C");
}

public BaseC()
{
Console.WriteLine("構造方法C");
}
public new void Invoke()
{
Console.WriteLine("Invoke---BaseC");
}
}

class Program
{
static void Main(string[] args)
{
BaseC bc = new BaseC();
bc.Invoke();
}
}
}

測試信息---靜態變量C
靜態構造方法C
測試信息---實例變量C
測試信息---靜態變量B
靜態構造方法B
測試信息---實例變量B
測試信息---靜態變量A
靜態構造方法A
測試信息---實例變量A
構造方法A
構造方法B
構造方法C
Invoke---BaseC

1、先靜態的東東在前面,靜態變量>靜態構造方法

2、從子類到父類(非靜態構造方法除外,確實從父類到子類,與Java一樣);先子類的靜態——>實例,在父類靜態——>實例…………父類構造方法——>子類構造方法

執行順序:

1. 初始化ChildClass的靜態字段(按聲明順序)

2. 初始化ChildClass的靜態構造函數

3. 初始化ChildClass的實例字段

4. 調用ChildClass的構造函數,並在此中斷, 調用ParentClass的構造函數, 導致ParentClass開始初始化

5. 初始化ParentClass的靜態字段

6. 初始化ParentClass的靜態構造函數

7. 初始化ParentClass的實例字段

8. 調用ParentClass的實例構造函數

9.ParentClass初始化完畢, 調用ChildClass的構造函數,完成創建

Copyright © Linux教程網 All Rights Reserved