您的位置:首页 > 编程语言 > Java开发

Java继承 学习 && 类初始化顺序

2015-11-14 20:31 375 查看
reference

private是私有成员,子类不可访问,和被override的类都要通过super访问。变量没有重写之说,只有屏蔽

类的继承知识点

(1)java不支持多重继承,也就是说子类至多只能有一个父类

(2)子类继承了其父类中不是私有的成员变量和成员方法,作为自己的成员变量和方法

(3)子类中定义的成员变量和父类中定义的成员变量相同时,则父类中的成员变量不能被继承

(4)子类中定义的成员方法,并且这个成员方法的名字,返回类型,及参数个数和类型与父类的某个成员方法完全相同,则父类的成员方法不能被继承。

class Ttest {
public static void main(String[] args){
B b=new B(0);
int y=b.getY();
}
}

class A {
public static int x=2; //1.
private int y=2;      //2.
protected int z=3;      //5.
A(){                      //3.
x=x+1;
showX();        //4.
}
public void showX(){
System.out.println("A.x="+x);
}
public int getY(){
return y;
}
}

class B extends A {
B(int x){
x=x+2;                 //只对局部x操作
showX();
}
public void showX(){
System.out.println("B.x="+x);
}
public int getY(){ //6.
System.out.println("B.z=" + z);
System.out.println("B.y="+(super.getY()+x));
return super.getY()+x;
}
}
/**
//B.x=3 会默认先调用父类的super,A,但是输出函数是多态的
//B.x=3 B自己输出
//B.z=3
//B.y=5
1. public static int x被继承到B,成为B的私有域。
2. B中仍然有一个名为y的域,但是无法直接访问,需要通过super.getY()
3. 如果子类构造函数没有显式调用超类构造函数,将会自动调用超类的无参构造函 数,若超类没有无参构造函数,子类中又没有显式调用,则编译器报错
4. java默认动态绑定机制,若不需要动态绑定则将方法定义为final阻止继承
5. 类A的protected修饰符的数据或方法,可以被同个包中的任何一个类访问(包括子类),也可以被不同包中的A的子类访问。
6. 覆盖一个方法时,子类的方法可见性不能低于父类方法的可见性。
*/

public abstract class A {
int i=1;
// 有没有是一样的
// public void printI() {
//   System.out.println("i="+i);
// }
}
public class B extends A{
public int i=2;
public void printI(){
super.printI();
}
public static void main(String[] args){
B b= new B();
b.printI();

}
}
/**
输出1
jvm的执行过程
(1)子类B 的构造方法被调用,实例化一个B对象,B对象的成员被初始化
(2)jvm隐含的调用父类的构造方法,实例化一个A对象,A对象的成员被初始化。
(3)由于A对象的printI()未被屏蔽,所以调用的A对象的printI()函数。
那么,在这里A的成员函数当然是访问自己的成员变量了。
*/

/**
super关键字在java中的作用是使被屏蔽的成员变量或者成员方法或变为可见,或者说用来引用被屏蔽的成员变量和成员成员方法。super是用在子类中,目的是访问直接父类中被屏蔽的成员
*/

---
public class A {

public int m = 1;

public void view(){
System.out.println(this.m);
System.out.println(this.getClass());
}

}

public class B extends A{
public int m = 2;
/**
*  @Override
*  public void view(){
*      System.out.println(this.m);
*      System.out.println(super.m);
*      System.out.println(this.getClass());
*  }
*/

public static void main(String[] args) {
B b = new B();
b.view();
}
}
/**
看执行结果:
1
class B

而如果将注释去掉,即重写view方法,再看结果:
2
1
class B

从结果即可以看出子类中有两个相同名称的成员变量,所以成员变量没有重写
*/


更新一道携程笔试题

public class Base
{
private String baseName = "base";
public Base()
{
callName();
}

public void callName()
{
System. out. println(baseName);
}

static class Sub extends Base
{
private String baseName = "sub";
public void callName()
{
System. out. println (baseName) ;
}
}
public static void main(String[] args)
{
Base b = new Sub();
}
}
// null
/**
类初始化顺序:
1. static按照写的顺序随类加载一起初始化
2. 其他写上初始值的都是在构造函数时初始化(有父类的先去父类中初始化隐含)
3. 由于多态,Base调用的callName是子类的函数,此时this指向为子类的baseName,还没初始化。因此为null
*/


再来一发面试题:

import java.awt.print.Book;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;

/**
* Created by bingone on 15/11/13.
*/
public class hibernate<T extends Number> {
public T v;
public static void main(String[] args) throws NoSuchFieldException {
hibernate<Double> h = new hibernate<Double>();
System.out.println( h.getClass().getField("v").getGenericType() );
}
}
class T  implements Cloneable{
public static int k = 0;
public static T t1 = new T("t1");
public static T t2 = new T("t2");
public static int i = print("i");
public static int n = 99;

public int j = print("j");
{
print("构造块");
}

static {
print("静态块");
}

public T(String str) {
System.out.println((++k) + ":" + str + "    i=" + i + "  n=" + n);
++n; ++ i;
}

public static int print(String str){
System.out.println((++k) +":" + str + "   i=" + i + "   n=" + n);
++n;
return ++ i;
}

public static void main(String[] args){
T t = new T("init");
}
}
/**
1:j   i=0   n=0
2:构造块   i=1   n=1
3:t1    i=2  n=2
4:j   i=3   n=3
5:构造块   i=4   n=4
6:t2    i=5  n=5
7:i   i=6   n=6
8:静态块   i=7   n=99
9:j   i=8   n=100
10:构造块   i=9   n=101
11:init    i=10  n=102
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: