黑马程序员技术交流社区
标题:
super的解释
[打印本页]
作者:
yanghu
时间:
2014-4-18 19:02
标题:
super的解释
QQ截图20140418185905.png
(144.07 KB, 下载次数: 19)
下载附件
2014-4-18 19:00 上传
我知道super是指向父类,我想问super这个引用是怎么来的?父类没有初始化,怎么会有super这个地址引用?
作者:
sanguodouble1
时间:
2014-4-18 19:11
本帖最后由 sanguodouble1 于 2014-4-18 19:14 编辑
你好,如果你实例化了一个子类的话,父类是被默认初始化的,
也就是说,子类内部是包含所有父类资料的
补充一下,这个原理是这样的:
子类构造方法的一个句就是调用父类构造方法,如果子类没有主动调用,
那么编译器就自动调用父类无参的构造方法,如果子类没有调用,父类又没有无参构造方法,那么肯定报错。
不信你试试
作者:
yanzhendong
时间:
2014-4-18 19:11
子类的构造函数第一句默认是super(),也就是说子类在初始化自己的时候先初始化父类,等父类初始化完毕后再初始化自己
作者:
月光海
时间:
2014-4-18 19:23
java中的super和this有类似的理解,但是不同的,就是继承时需要初始化父类,层层迭代,由祖宗开始初始化。
package com.cbh.this_test;
class Super_father
{
int i;
String father=”我是第一个爸爸”;
Super_father(int x)
{
i=x;
System.out.println(“我是i=”+i);
}
Super_father()
{
System.out.println(father+”,”+”而且是无参构造”);
}
}
class father1 extends Super_father
{
int i;
String father=”我是第二个爸爸”;
father1(int x)
{
i=x;
System.out.println(“我是J=”+i);
}
father1()
{
System.out.println(father+”,”+”而且是无参构造”);
}
}
public class Super_test extends father1
{
int s=10;
String son=”I’m a son”;
Super_test()
{
super(10);//调用父类的有参构造方法
// super(); //
super(s);//不能使用两次,和this一样
System.out.println(super.father);
}
Super_test(int k)
{
super(k);
}
public static void main(String[] args)
{
new Super_test();
new Super_test(5);
}
}
//继承时,需要初始化父类,父类需要再继承爷爷类,那么也需要初始化爷爷类,如此下去。如果没有调用特定的构造方法,就默认调用无参构造。反正就是需要初始化。
//从字面上理解,super指的是超类,所谓超类可以简单点理解为,超出本类,所以需要一个前提,就是必须有类给它超,所以它需要一个直接父类,当然,父类可以有爷爷类,用的时候,知道要初始化就行了。
希望能帮到你
作者:
孙旌棋
时间:
2014-4-20 16:52
本帖最后由 孙旌棋 于 2014-4-20 16:53 编辑
首先, 子类实例化的过程中其实第一句就是你super(), 如果你不写, 则由虚拟机为你加载
如果父类的构造函数中有参数, 那么自类实例化的时候, 需要指定的哦, 详细的请看代码中的注释
class Father {
int num;
private String name;
private int age;
Father() {
num = 1;
System.out.println("孙旌棋");
}
Father(int x) {
System.out.println(x);
}
Father(String name, int age) {
this.name = name;
this.age = age;
System.out.println(name + " " + age);
}
}
class Son extends Father {
Son() {
// super(); 第一行有默认的隐式语句super(),由虚拟机加载
System.out.println("孙旌棋,863523704");
}
Son(int x) {
// this(); 当子类中有一个构造函数访问父类的构造函数时,可以用this(); super(2);//
// 有参数时需要手动定义super(),语句来指定
System.out.println(x);
}
Son(String name, int age) {
super(name, age);// 父类已实现,子类可以直接拿来用
}
}
复制代码
作者:
左拉
时间:
2014-4-20 19:32
本帖最后由 左拉 于 2014-4-20 19:42 编辑
通过用static来定义方法或成员,为我们编程提供了某种便利,从某种程度上可以说它类似于C语言中的全局函数和全局变量。但是,并不是说有了这种便利,你便可以随处使用,如果那样的话,你便需要认真考虑一下自己是否在用面向对象的思想编程,自己的程序是否是面向对象的。
好了,现在开始讨论this&super这两个关键字的意义和用法。
在Java中,this通常指当前对象,super则指父类的。当你想要引用当前对象的某种东西,比如当前对象的某个方法,或当前对象的某个成员,你便可以利用this来实现这个目的,当然,this的另一个用途是调用当前对象的另一个构造函数,这些马上就要讨论。如果你想引用父类的某种东西,则非super莫属。由于this与super有如此相似的一些特性和与生俱来的某种关系,所以我们在这一块儿来讨论,希望能帮助你区分和掌握它们两个。
在一般方法中
最普遍的情况就是,在你的方法中的某个形参名与当前对象的某个成员有相同的名字,这时为了不至于混淆,你便需要明确使用this关键字来指明你要使用某个成员,使用方法是“this.成员名”,而不带this的那个便是形参。另外,还可以用“this.方法名”来引用当前对象的某个方法,但这时this就不是必须的了,你可以直接用方法名来访问那个方法,编译器会知道你要调用的是那一个。
public class DemoThis{
private String name;
private int age;
DemoThis(String name,int age){
setName(name);
//你可以加上this来调用方法,像这样:this.setName(name);但这并不是必须的
setAge(age);
this.print(); }
public void setName(String name){
this.name=name;//此处必须指明你要引用成员变量
}
public void etAge(int age){
this.age=age;
}
public void print(){
System.out.println("Name="+name+" ge="+age);
//在此行中并不需要用this,因为没有会导致混淆的东西
}
public static void main(String[] args){
DemoThis dt=new DemoThis("Kevin","22");
这段代码很简单,不用解释你也应该能看明白。在构造函数中你看到用this.print(),你完全可以用print()来代替它,两者效果一样。下面我们修改这个程序,来演示super的用法。
class Person{
public int c;
private String name;
private int age;
protected void setName(String name){
this.name=name;
}
protected void setAge(int age){
this.age=age;
}
protected void print(){
System.out.println("Name="+name+" Age="+age);
}
}
public class DemoSuper extends Person{
public void print(){
System.out.println("DemoSuper:");
super.print();
}
public static void main(String[] args){
DemoSuper ds=new DemoSuper();
ds.setName("kevin");
ds.setAge(22);
ds.print();
}
}
复制代码
在DemoSuper中,重新定义的print方法覆写了父类的print方法,它首先做一些自己的事情,然后调用父类的那个被覆写了的方法。输出结果说明了这一点:
DemoSuper:
Name=kevin Age=22
这样的使用方法是比较常用的。另外如果父类的成员可以被子类访问,那你可以像使用this一样使用它,用“super.父类中的成员名”的方式,但常常你并不是这样来访问父类中的成员名的。
在构造函数中构造函数是一种特殊的方法,在对象初始化的时候自动调用。在构造函数中,this和super也有上面说的种种使用方式,并且它还有特殊的地方,请看下面的例子:
class Person{
public static void prt(String s) {
System.out.println(s);
}
public Person(){
prt("A Person.");
}
public Person(String name){
prt(name);
}
}
public class Chinese extends Person {
Chinese() {
super(); // 调用父类构造函数(1)
prt("A chinese.");// (4)
}
Chinese(String name) {
super(name);// 调用父类具有相同形参的构造函数(2)
prt("his name is:" + name);
}
Chinese(String name, int age) {
this(name);// 调用当前具有相同形参的构造函数(3)
prt("his age is:" + age);
}
public static void main(String[] args) {
Chinese cn = new Chinese();
cn = new Chinese("kevin");
cn = new Chinese("kevin", 22);
}
复制代码
在这段程序中,this和super不再是像以前那样用“.”连接一个方法或成员,而是直接在其后跟
上适当的参数,因此它的意义也就有了变化。super后加参数的是用来调用父类中具有相同形式的
构造函数,如1和2处。this后加参数则调用的是当前具有相同参数的构造函数,如3处。当然,在
Chinese的各个重载构造函数中,this和super在一般方法中的各种用法也仍可使用,比如4处,你
可以将它替换为“this.prt”(因为它继承了父类中的那个方法)或者是“super.prt”(因为它
是父类中的方法且可被子类访问),它照样可以正确运行。但这样似乎就有点画蛇添足的味道
了。
作者:
菠萝包丶
时间:
2014-4-20 19:33
本帖最后由 菠萝包丶 于 2014-4-20 19:37 编辑
当对子类的对象进行初始化时,父类的构造函数也会运行!
那是因为子类的构造函数默认第一行有一条隐式的语句super()
super():会访问父类中空参数的的构造函数,而且子类中所有的构造函数默认第一行都是super()
zi()
{
//super();
}
复制代码
由于父类中的数据子类可以直接获取,所以子类对象建立时,需要先查看父类是如何对这些数据进行初始化的
所以子类在对象初始化时,要先访问一下父类中的构造函数。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2