黑马程序员技术交流社区

标题: 要疯了,一个关于类继承,调用构造函数的问题 [打印本页]

作者: 斗胆潇洒    时间: 2013-8-23 19:13
标题: 要疯了,一个关于类继承,调用构造函数的问题
本帖最后由 斗胆潇洒 于 2013-8-23 20:35 编辑

有这样三个类,Person、Student、GoodStudent。其中GoodStudent继承于Student,Student继承于Person。问:在GoodStudent中是否能指定调用Person的哪个构造函数?
认真看哦,是GoodStudent-->Student-->Person的单线继承方式,问子类能去指定爷爷类的构造函数吗?
我能证明的是得通过父类Student的构造函数,间接性的去指定爷爷类Person的构造函数,但能直接(非间接)在GoodStudent指
定Person的某个构造函数吗?部分代码:
以下是3个类的部分构造函数
Person(String s1,String s2)//Person构造函数有多个,这是其中一个
{
syso(s1+s2+"aa");
}

Student(Stirng s)//多个,这是其中一个
{
super(s,"bb");
}

GoodStudent ()
{
  super("cc");
}
//这样 在GoodStudent  中通过Student(Stirng s) 我就能间接指定 Person的构造函数为Person(String s1,String s2)了,
//但有在 GoodStudent   类中直接指定的方法吗?
烦恼就在这啊,你说不能指定嘛,又能通过Student的构造函数去间接指定,你说能指定嘛,严格说的话在GoodStudent中我真找
不出办法去直接性的指定Person的某个构造函数。
有谁做过吗?能帮我分析下不,明确下解答,是说不能呢,还是说能呢?



作者: 薛鹏鹏    时间: 2013-8-23 19:31
利用反射试试
作者: 斗胆潇洒    时间: 2013-8-23 19:33
额,跪求,其他题目都简单,就这题我出现了歧义,我该咋回答呢,也来个模凌两可的回答?
作者: 斗胆潇洒    时间: 2013-8-23 19:39
薛鹏鹏 发表于 2013-8-23 19:31
利用反射试试

{:soso_e103:},这是简单题,不会牵涉到反射吧,额,我怕把你们也搅糊涂了,有java基础的就给我说明下,子类能指定爷爷类的某个构造函数不?

我得到证实就ok了,拜谢.....

作者: 杨增坤    时间: 2013-8-23 19:46
/**
* Person 类
*
*/
public class Person {
        private String name;

        public Person(String name) {
                super();
                this.name = name;
                System.out.println("Person 构造函数");
        }
}
/**
* Student 类
*
*/
public class Student extends Person {

        public Student(String name) {
                super(name);
                System.out.println("Student 构造函数");
        }

}

import java.lang.reflect.InvocationTargetException;
/**
* GoodStudent 类
*
*/
public class GoodStudent extends Student {

        public GoodStudent(String name) {
                super(name);
                System.out.println("GoodStudent 构造函数");
        }
/**
* 直接获取Person的构造方法,然后返回其实例对象
*/
        public static Person getPerson(String name) {

                Person p=null;
                try {
                        p = Person.class.getConstructor(String.class).newInstance(name);
                } catch (Exception e) {
                        e.printStackTrace();
                }
                return p;

        }
}

public class Text{
public static void main(String[] s) {
             new GoodStudent("张三");//这是我们正常情况下的做法,
                //GoodStudent.getGoodStudent("李四");
        }

}
结果是:
Person 构造函数
Student 构造函数
GoodStudent 构造函数


但是如果是这样呢:
public class Text1{
public static void main(String[] s) {
            // new GoodStudent("张三");//这是我们正常情况下的做法,
                GoodStudent.getPerson("李四");//使用返回的构造
        }

}

结果:
Person 构造函数

从运行结果中就可以看出,第二种方法,是直接使用的Person的构造方法
希望对你有帮助



作者: xuluheng718    时间: 2013-8-23 19:48
本帖最后由 xuluheng718 于 2013-8-23 19:52 编辑

明显是不能,这是为什么呢?因为JAVA只支持单继承,其实JAVA根本就没有爷爷类这一说,JAVA任何类只能有一个父类,你的Student类继承至Person类,GoodStudent继承至Student,看上去GoodStudent和Person有关系,其实你仔细想想,他们真的有关系??根据JAVA单继承关系GoodStudent的父类是Student而不是Person,那么你还能直接调用父类的构造方法?当然间接通过GoodStudent的父类Student去调用是可以的
作者: 斗胆潇洒    时间: 2013-8-23 20:01
本帖最后由 斗胆潇洒 于 2013-8-23 20:03 编辑
forward 发表于 2013-8-23 19:46
/**
* Person 类
*

谢谢,其实开始我自己也写了种先有
Person(String s)//一构造函数{
syso("...Person:"+s);
}


再GoodStudent类中创建静态
public static void getPerson(String s)
{
        new Person(s);
}


再在Test9类的main中
直接写语句 GoodStudent.getPerson("张三");
输出结果:...Person:张三


但是我自己否认了这样的写法,不知道可以不,
相比下 我觉得反射去获取构造函数是不是复杂了点啊

作者: xuluheng718    时间: 2013-8-23 20:04
再说一句,要想直接调用父类的父类的构造方法,根本是无稽之谈
作者: HM汪磊    时间: 2013-8-23 20:08
public class Test9 {

        public static void main(String[] args) {
                // TODO Auto-generated method stub
                         Student s1 = new Student(); //创建 Student类实例对象
                System.out.println("-------------------------------");
                
                GoodStudent g1 = new GoodStudent(); //创建 GoodStudent类实例对象
                System.out.println("-------------------------------");  
        }

}

//创建Person类
class Person{
        //空参数构造函数
        Person(){
                System.out.println("Person 空参数构造函数");
        }
        //有一个参数的构造函数
        Person(String str){
                System.out.println("Person 一个参数的构造函数");
        }
        //有两个参数的构造函数
        Person(String arg,String str){
                System.out.println("Person 两个参数的构造函数");
        }
       
}
//创建Student类并继承Person类
class Student extends Person{
        //空参数构造函数
        Student(){
                super();//调用Person类中空参数构造函数
                System.out.println("Student 空参数构造函数");
        }
        //有一个参数的构造函数
        Student(String str){
                System.out.println("Student 一个参数的构造函数");
        }
}
//创建GoodStudent类并继承Student类
class GoodStudent extends Student{
        //空参数构造函数
        GoodStudent(){
                super("abc");//此处调用Student类中有一个参数的构造函数
                System.out.println("GoodStudent 空参数构造函数");
        }

}
作者: 斗胆潇洒    时间: 2013-8-23 20:11
xuluheng718 发表于 2013-8-23 20:04
再说一句,要想直接调用父类的父类的构造方法,根本是无稽之谈

额,谢谢,但java的单继承不是相对于横向的吗?
不是说java每个类都是Object的子类,那person也是继承于Object,
但Person又能派生出Student,
而且用代码能运行这种纵向的单线继承的代码啊
不过我也觉得,只能是间接性的去调用爷爷类的构造函数了

作者: 斗胆潇洒    时间: 2013-8-23 20:19
HM汪磊 发表于 2013-8-23 20:08
public class Test9 {

        public static void main(String[] args) {

呵呵,我现在的代码就是跟你的类似哦,也是间接去指定Person的构造函数,也许就只能这样了吧,毕竟要符合这几道简单题的简单性,方法复杂了反而有点偏了。

作者: 穿靴子的猫    时间: 2013-8-23 20:22
不管你继承谁 你是不是都能调用Object中的toString()? 哪怕是单线继承 儿子继承爸爸 爸爸继承爷爷
构造的时候都是儿子先构造出父亲 父亲再继续向上找 找到爷爷 这个时候爷爷还是要向上找 找到Object最大的父类 直到终点才算构造结束 这个时候才会再继续向下 拥有爷爷和爸爸的公开属性和方法
作者: xuluheng718    时间: 2013-8-23 20:25
斗胆潇洒 发表于 2013-8-23 20:11
额,谢谢,但java的单继承不是相对于横向的吗?
不是说java每个类都是Object的子类,那person也是继承于Ob ...

JAVA中,当一个类显示的继承了另一类,那么就不是直接继承Object了,而是继承自父类继承的Object

作者: 斗胆潇洒    时间: 2013-8-23 20:34
嗯,谢谢各位了,我以前学c++的,现在初学java,有些地方是混了,交流够帮助很大,多谢各位解惑额,结了
作者: xuluheng718    时间: 2013-8-23 20:39
forward 发表于 2013-8-23 19:46
/**
* Person 类
*

你这种方式,不能证明任何问题,因为你的整个方法中,自始至终只产生了一个对象那就是Person,GoodStudent对象并没有被创建,因为GoodStudent的getPerson是静态的,而JAVA创建对象的依据是构造方法
作者: HM张博文    时间: 2013-8-24 15:52
问题太深奥了,静等高人出现哦




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2