`
haibin369
  • 浏览: 58501 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

关于Java中的多态

    博客分类:
  • Java
阅读更多

 

一、继承体系中的初始化顺序 

当我们使用new创建一个对象的时候,这个对象会在类的继承体系中按以下顺序执行初始化:

 

  1. 初始化父类的静态变量和静态代码块,按它们在代码中定义的顺序执行(先定义先执行);
  2. 初始化子类的静态变量和静态代码块,按它们在代码中定义的顺序执行(先定义先执行);
  3. 初始化父类的实例变量和实例代码块,按它们在代码中定义的顺序执行(先定义先执行);
  4. 执行父类的构造方法;
  5. 初始化子类的实例变量和实例代码块,按它们在代码中定义的顺序执行(先定义先执行);
  6. 执行子类的构造方法。

当该类存在多层次的继承体系时,则按以上顺序递归地执行初始化。

 

/**
 * 父类
 */
class SuperClass {
	//父类的静态代码块
	static {
		System.out.println("Initalizing static block in SuperClass\n");
	}
	
	//父类的实例代码块
	{
		System.out.println("Initalizing instance block in SuperClass\n");
	}
	
	//父类的静态变量
	public static Var StaticSuperVar = new Var("static variable in SuperClass");
	
	//父类的实例代变量
	public Var superVar = new Var("variable in SuperClass");
	
	//父类的构造方法
	public SuperClass() {
		System.out.println("Initalizing SuperClass\n");
	}
}

/**
 * 子类
 */
class SubClass extends SuperClass {
	//子类的静态变量
	public static Var StaticSubVar = new Var("static variable in SubClass");
	
	//子类的实例变量
	public Var subVar = new Var("variable in SubClass");
	
	//子类的静态代码块
	static {
		System.out.println("Initalizing static block in SubClass\n");
	}
	
	//子类的实例代码块
	{
		System.out.println("Initalizing instance block in SubClass\n");
	}
	
	//子类的构造方法
	public SubClass() {
		System.out.println("Initalizing SubClass\n");
	}
}

/**
 * 辅助类
 */
class Var {
	public Var(String name) {
		System.out.println("Initalizing " + name + "\n");
	}
}

/**
 * 测试类
 */
public class InitOrderTest {
	public static void main(String[] args) {
		SubClass subClass = new SubClass();
	}
}

运行结果:

Initalizing static block in SuperClass

Initalizing static variable in SuperClass

Initalizing static variable in SubClass

Initalizing static block in SubClass

Initalizing instance block in SuperClass

Initalizing variable in SuperClass

Initalizing SuperClass

Initalizing variable in SubClass

Initalizing instance block in SubClass

Initalizing SubClass

 

二、多态中的属性

在Java中,只有方法调用是多态的,而属性访问是在编译器解析的。表面上看是子类重写了父类的某个属性,实际上是子类获得了两个同名的属性,使用父类引用访问的属性是父类的属性,而子类引用则默认访问子类的属性,要访问父类属性则必须显式用super。

class SuperClass {
    public int field = 0;

    public int getField() {
        return field;
    }
}

class SubClass extends SuperClass {
    public int field = 1;

    public int getField() {
        return field;
    }

    public int getSuperField() {
        return super.field;
    }
}

public class FieldTest {
    public static void main(String[] args) {
        SuperClass sup = new SubClass();
        System.out.println("sup.field = " + sup.field + ", sup.getField() = " + sup.getField());

        System.out.println();

        SubClass sub = new SubClass();
        System.out.println("sub.field = " + sub.field + ", sub.getField() = " + sub.getField());
        System.out.println("sub.getSuperField() = " + sub.getSuperField());
    }
}

 结果

sup.field = 0, sup.getField() = 1

sub.field = 1, sub.getField() = 1
sub.getSuperField() = 0

 

三、私有方法与静态方法

当子类拥有与父类的某个私有方法相同签名的方法时,表面上是子类重写了父类的私有方法,实际上因为私有方法是隐式设成final的,而且对子类是屏蔽的,所以这种情况下是子类定义了新的方法,而不存在重载。

class SuperClass {
    private void privateFunc(){
        System.out.println("SuperClass");
    }

    public static void main(String[] args) {
        SuperClass sup = new SubClass();
        sup.privateFunc();
    }
}

class SubClass extends SuperClass {
    private void privateFunc(){
        System.out.println("SubClass");
    }
}

 结果

SuperClass

 

静态方法也不具有多态性,因为静态方法是与类而不是对象相关联的。

class SuperClass {
    public static void func(){
        System.out.println("SuperClass");
    }
}

class SubClass extends SuperClass {
    public static void func(){
        System.out.println("SubClass");
    }
}

public class FieldTest {
    public static void main(String[] args) {
        SuperClass sup = new SubClass();
        sup.func();
    }
}

 结果:

SuperClass

 

四、方法签名冲突

当同时实现多个接口或者同时实现接口与继承某个父类时,如果在这些被实现的接口和被继承的父类中存在签名相同但返回类型不相同的方法时,会出现冲突并造成编译错误。

interface Interface{
        public void func();

        public void anotherFunc();
    }

    interface AnotherInterface{
        public int func();
    }

    class SuperClass{
        public int anotherFunc(){
            return 0;
        }
    }

    class SubClass extends SuperClass implements Interface, AnotherInterface{
        @Override
        public void func() {
            //方法编译错误:
            //‘func()' in 'SubClass' clashes with 'func()' in AnotherInterface;
            // attempting to use incompatible return type
        }

        @Override
        public void anotherFunc() {
            //方法编译错误:
            //‘anotherFunc()' in 'SubClass' clashes with 'anotherFunc()' in SuperClass;
            // attempting to use incompatible return type
        }
    }

 

五、变量冲突

与方法签名冲突类似,同名的属性(变量)也会出现冲突。

interface Interface {
    String FIELD = "Interface";
}

class SuperClass {
    public String FIELD = "SuperClass";
}

class SubClass extends SuperClass implements Interface {
}

public class FieldConflictTest {
    public static void main(String[] args) {
        SubClass cls = new SubClass();
        //编译错误:
        //Reference to 'FIELD' is ambiguous,
        //both 'SuperClass.FIELD' and 'Interface.FIELD' match
        System.out.println(cls.FIELD);
    }
}

 

0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics