Java基础_super()用法和继承的关系

下面的文章是转载自http://greateryang.blog.163.com/blog/static/81953375201232661845898/


看完这篇文章,你可以理顺super()的作用,和使用该注意的情况;

class A{
int x;
public A(){
this.print() ;
}

public void print(){
System.out.println("x = " + x) ;
}
};
class B extends A{
int x = 100 ;

public B(int x){

super();
this.= x ;

}
public void print(){
System.out.println("x = " + x) ;
}

  1. 这里出个题目:为什么打印出来x的值是0,如果不能理解的话再看下一问!
  2. 再出一个题目: 子类里面的每个构造函数里都有隐式的super(),为什么一定要有super()呢 !
  3. 看到第二个问题是不是第一个问题比较清晰了,原来是有默认的super();在起作用,那么第二个问题是不是还没有答案!
下面认真看吧,几乎上解决了所有的super的问题!
这个问题中涉及到super的,还涉及到继承!

关于继承这是个大问题:要提到内存机制了,认真看看,后面还给你写了代码分析,是继承和super()大总结!
内存机制:
父类和子类是占用同一块内存的,子类是依附于父类的,先有父类再有子类,只不过子类在父类的基础上增加了自己的方法和属性。
所以:     一个子类对象的产生,必须先调用父类的构造方法产生一个父类实例,然后在这个实例基础上添加子类自己的东西,但是没有父类的构造方法子类根本不可能有构造方法!
问题来了: 你会问,我的父类就没有写构造方法,但是我的子类有写构造方法啊,各种有,有参的无参的都很正常啊,而且运行也很好啊,如下面的这个:
  1. public class Tet extends Text1{
  2.                 public Tet(){                    构造一
  3.              }
  4.                 public Tet(int a){             构造二,竟然还是有参的
  5.                  }
  6.                 public static void main(String[] args){
  7.                  }
  8.         }

  9. class Text1{
  10.         }  

有这个疑问很正常!!   这就涉及到另一个知识点,构造方法!!
详解:
当每一个类建立的时候,系统都默认添加一个没有参数也没有方法体的构造函数,还记得吧!
所以父类中有构造方法,而且是系统默认存在的构造方法,所以你子类才可能建立构造方法!

问题又来了: 子类有无参的构造方法是合理的了,但是我还有有参的构造方法啊,怎么还正确!
  1. public class Tet extends Text1{
  2.                 public Tet(){
  3.                 //super();     // 正是系统默认提供的super();在起作用,正是默默的它,指向了父类默认存在的构造函数,所以你的代码才得以正确运行,都是它的功劳啊!!
  4.              }
  5.                 public Tet(int a){
  6.                 //super();    // 正是系统默认提供的super();在起作用,正是默默的它,指向了父类默认存在的构造函数,所以你的代码才得以正确运行,都是它的功劳啊!! 
  7.                                  //在这里我们给它一首赞歌
  8.                  }              //啊!是它在内存中给了子类一个机会,子类才得以自由实例化,啊!是它悄悄地藏在这里,你不知不觉!啊!是它.... 好了够了啊!
  9.                 public static void main(String[] args){
  10.                  }
  11.         }

  12. class Text1{          
  13.         }

当你吧某个子类的构造函数里面写成super(100)等的时候,你就会发现出错了,就是这个道理,因为父类默认的构造函数是没有参数的!
问题又来了: 只能说小伙很有思想啊,下面的代码又出错了,认真看看!
  1. public class Tet extends Text1{
  2.                 public Tet(){                    // 这里为什么会报错呢,父类不给面子了吗??? 我们的super()呢,刚才还为你唱歌,这会怎么不起作用了!!你陷入了疑问。。。。
  3.              }
  4.                 public Tet(int a){             // 这里为什么会报错呢,父类不给面子了吗??? 我们的super() 呢,刚才还为你唱歌,这会怎么不起作用了!!你陷入了疑问 。。。。 
  5.                  }
  6.                 public static void main(String[] args){
  7.                  }
  8.         }

  9. class Text1{
  10.         public Text1(int a){       //  原来父类大哥,刚才自己努力了一把,这有了一个有参的构造函数!!
  11.          }
  12.         }

这是问什么呢??,这就是因为,系统给子类构造函数默认的super(),找不到父类的无参的构造函数了,
问题又来了: 为什么找不到了呢!他不是默认的吗!! 
现在父类已经变身了没看到吗,已经有了人自己的有参构造方法了,系统不提供默认的构造方法了,有了自己的房子还想住国家的公租房?开玩笑吧!

问题又来了: 那现在怎么办呢?如何能正常编译呢
这里提供两种方法
A、子类构造方法中全部自定义为 有参 super, 就像super(100)调用父类存在的带参数的构造方法!
B、父类中重新定义无参的构造方法,   public Text1(){      方法体可以根据需要取舍!
                                                                        };



例子2:

public class Base {
	protected int flag = 5;
	protected String name;
	protected int age;
	public Base(){
		System.out.println("Base");
	}
	public Base(String a){
		System.out.println("Base");
	}
	protected void setName(String name){
		this.name = name;
	}
	protected void setAge(int age){
		this.age  = age;
	}
	protected void foo(){
		System.out.println("foo in father.\n"+
				"age = "+age+",\t"
					+"name = "+name);
	}
}


public class Checket extends Base{
//	private int flag = 100;
	public Checket(){
		
		super();
		//当不写super();系统会默认添加一个super();进来
		//super("1");//调用父类构造方法
		System.out.println("Checket");
	}
	public Checket(String name){
		//super("1");
		super();
	}
	@Override
	public void foo(){
		System.out.println("flag = "+flag);
		//this.flag = 1;
		super.foo();
		System.out.println("foo in son");
		++flag;
		System.out.println("flag = "+flag);
		
	}
	public static void main(String [] args){
		Checket c = new Checket();
		c.setAge(1);
		c.setName("LPY");
		c.foo();	
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值