黑马程序员技术交流社区

标题: 求大神解释一下 [打印本页]

作者: 唐小斗    时间: 2016-6-15 10:12
标题: 求大神解释一下
public class Person {
    private String name;
    public Person(){
        Class classs = this.getClass();         
        System.out.println(this);
        this.name = "ths";     //@这是我的一个疑问
        System.out.println(this);
    }
    public String getName(){
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
public class Student extends Person{}
@Test
    public void testExtends(){
        new Student();
    }
简单说明一下上面的代码:一个student类继承person类,在测试类中我new了一个student对象,我们都知道在创建子类对象时默认会去调用父类的构造方法所以构造方法中的this代表student对象,可是让我很不明白的是this.name,不是说子类不继承父类的私有属性吗?那么这个this.name又算神马?不是说子类不可以直接使用吗?求大神详解一下!


作者: 15603757970    时间: 2016-6-15 10:12
楼主,我是这样认为的,这里的this.name肯定是指的Person类本身,这没有错吧,当我们调用学生类无参构造的时候,默认使用的是父类的,this.name和Person中的getName表达的意思不是一样的吗,都是返回本类的成员变量,所以当你Student s = new Student();学生的时候,显示的s.geName还是显示ths,你想想.
作者: 唐小斗    时间: 2016-6-15 14:54
15603757970 发表于 2016-6-15 14:10
楼主,我是这样认为的,这里的this.name肯定是指的Person类本身,这没有错吧,当我们调用学生类无参构造的时候, ...

,这里的this.name肯定是指的Person类本身的,可是我打印this是指student对象,这怎么理解?
作者: 唐小斗    时间: 2016-6-15 14:56
15603757970 发表于 2016-6-15 14:10
楼主,我是这样认为的,这里的this.name肯定是指的Person类本身,这没有错吧,当我们调用学生类无参构造的时候, ...

你说“这里的this.name肯定是指的Person类本身”可是打印this却是student对象地址,这怎么理解?还有我想问一下:子类继承父类对于父类的私有属性到底存在不存在子类的堆内存中?
作者: 阿姆1Q84    时间: 2016-6-16 00:58
本帖最后由 阿姆1Q84 于 2016-6-16 01:03 编辑

首先,你这个程序的测试类中没有main方法无法运行
退一步,讲程序正常运行,new Student(),创建子类的匿名对象,系统会通过子类的默认构造方法去访问父类的无参构造方法并对子类进行初始化数据,这个无参的构造方法也就是你自己所写的Person()这个构造方法,this代表的是子类对象的引用,此时也就是代表的是Student这个类的引用,System.out.println(this);打印输出也是Student这个类的对象的引用地址值,随后,在构造方法中this.name = "ths",进行的是对这个属性name 的显示初始化操作.
作者: 唐小斗    时间: 2016-6-16 09:51
阿姆1Q84 发表于 2016-6-16 00:58
首先,你这个程序的测试类中没有main方法无法运行
退一步,讲程序正常运行,new Student(),创建子类的匿名对象 ...

首先这是可以运行的用的是Junit测试,你最后所说的“在构造方法中this.name = "ths",进行的是对这个属性name 的显示初始化操作.”我知道是显示初始化操作,我想问这个name属性是属于哪个对象的?
作者: sgzqsw    时间: 2016-6-16 13:09
Student这个类的引用,System.out.println(this);打印输出是Student这个类的对象的引用地址值
你是在构造方法里命名的this.name ,子类调用父类构造方法,构造方法在父类中操作,这时this.name 是可以访问到名字的,也就是父类的名字,但是你构造函数执行完后,退出了构造方法后学生本身是没有name属性。这时name属性是父类的。等于间接帮父类命名了。而且你用Studentd调用getName方法因为学生没定义这个方法,还是返回父类去找,到了父类中看见rerun this.name  虽然这时对象是学生对象 ,但是因为学生没有name属性又继承了父类,所以调用返回的还是父类的名字。
作者: zhuhongbo    时间: 2016-6-16 13:32
this.name = "ths";  这代码表示的是通过this对指向父类Person对象name属性的初始化。
作者: dubei1993    时间: 2016-6-18 00:23
首先我也不太懂。程序我运行了下,会打印4个值。两个父类,两个子类地址。如果输出this.name 属性,最后一个是ths. 换句话说,子类的属性已经有了name属性。感觉各位的回答不够直接。换个角度想一下,继承了set和get方法却没有name属性。。很可怕
作者: 清凉    时间: 2016-6-19 00:14
和楼上想法差不多
作者: 小雨皮    时间: 2016-6-19 16:01
面向对象的继承,父类的是有对象,子类不能调用,但是,父类的构造函数里操作的方法总得实现吧?
作者: 爱逗猫的鱼    时间: 2016-6-20 01:24
创建子类对象时会默认访问父类的空参构造方法
作者: fulq1234    时间: 2016-6-20 07:10
Java继承的定义是“ Java继承是面向对象的最显著的一个特征。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力”
继承是针对“类”,
调用“属性”的时候,不能从继承方面想。
“this.属性 ”,表示本类属性。
你又会问了,那Student里面的this.name不是继承了Person的name属性吗?咱们可以从“新的类能吸收已有类的数据属性和行为,并能扩展新的能力”。这里想。新类也就是子类已经具备了属性name以后。再有以后的操作。那么在Student类中“this.name”,也是代表本类属性。

总起来说this关键字可以做三件事:
1, “this.属性 ”,表示本类属性

2,调用本类方法

3,this表示当前对象。


package aa;
public class AAA {
        public static void main(String args[]){
                Student ss=new Student();
        }
}
class Person {
    public String name="9";
    public Person(){            
        System.out.println(this);
        this.name = "ths";     //@这是我的一个疑问
        System.out.println(this.getClass().getName());  
        System.out.println(this.name);//"this.属性",表示本类属性
        this.print();//this表示当前对象Student,调用Student的方法print.
    }
    public String getName(){
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
        public void print() {
        }
}
class Student extends Person{
        public void print() {
                System.out.println("Student="+this.name);//子类继承父类的属性
        }
}
作者: bitwdh    时间: 2016-6-20 17:49
this.name = "ths"; 这句的意思是:将ths的字符串变量赋值给Person类中的name属性,通过this.name来代码属性Person的属性。
作者: 1499744937    时间: 2016-6-21 23:31
15603757970 发表于 2016-6-15 14:10
楼主,我是这样认为的,这里的this.name肯定是指的Person类本身,这没有错吧,当我们调用学生类无参构造的时候, ...

我也是这样认为的
作者: 爱逗猫的鱼    时间: 2016-6-22 00:57
this的含义是谁调用我就代表谁,this.getClass和this是Student的.this.name是Person的,两个this不是同一个引用对象。又没规定this是不变的,固定指向一个对象,它是通过引用来发挥作用的。
作者: 黎筱明    时间: 2016-6-23 02:05
你仔细看你的代码...你没发现问题吗..你new 学生对象的方法没有卸载学生类的大括号里面啊...
作者: 选择天涯    时间: 2016-6-24 16:55
刚接触这块,虽然我不懂.但首先我们得弄明白继承问题:  私有是可以继承的,  但是真私有就不能继承.
  所以我们得清楚的明白 类的属性是写在 .h文件  还是.m文件中
作者: 他的好    时间: 2016-6-24 20:44
this是一个关键字,他调用的就是本类中的成员变量,this可以被当作是本类中的一个对象,还有一个关键字是super他是访问父类中的成员的,继承中确实不能集成私有成员,这里的this.name是给Person中的变量name赋值。如果说的不对还请指点

作者: 冒泡儿    时间: 2016-6-26 00:44
父类要有有set,get方法,子类就可以调用私有的成员变量
作者: LoveGG    时间: 2016-6-26 01:16
    可是让我很不明白的是this.name,不是说子类不继承父类的私有属性吗?那么这个this.name又算神马?不是说子类不可以直接使用吗?求大神详解一下!
分析一下:
  1.说明一下子类可以继承父类私有属性,没有private修饰的变量可以 对象.name就表示这个属性,可以赋值(类似set方法)也可输出等等操作,但是private修饰变量之后就不能这样用了,只能setter,getter得到这个变量,但是他还是继承父类的属性,只是private的访问权限修饰符限定你不能直接使用实例变量,需要用方法访问,这就是面向对象思想,封装,让你继承使用,为了弥补单继承的缺陷就有了多态。所有的面向对象知识都是有关联的,好好理解,希望对你有帮助,祝成功!
作者: 大笑哈哈    时间: 2016-6-28 16:14
1,子类继承父类,在对子类对象构造之前会先调用父类构造    构造就是对对象进行初始化
2,this代表当前对象的引用
2,私有属性只能在本类中被访问.   
所以在父类中用this.name有什么不可以?
你的问题是  :子类不可以直接使用父类私有属性.     这句话是正确的  ,  意思是不能在子类中使用父类的私有属性,
没有说不能在父类使用父类属性.

作者: 610980097    时间: 2016-6-29 00:19
现在的this.name,等同于name
作者: 雪莲    时间: 2016-6-29 22:15
this调用的是父类的
作者: guowei    时间: 2016-6-30 16:55
this代表的是当前调用  
作者: 阿卜    时间: 2016-7-1 12:55
这里是父类的构造方法给私有变量name赋值的,你的子类只是实例化了一个Person对象,给name赋值的是Person类的构造方法Person()。子类并没有调用父类的私有变量name。
作者: xfbyxq    时间: 2016-7-3 20:23
15603757970 发表于 2016-6-15 14:10
楼主,我是这样认为的,这里的this.name肯定是指的Person类本身,这没有错吧,当我们调用学生类无参构造的时候, ...

this指向Student  而不是Person
作者: xfbyxq    时间: 2016-7-3 20:46
我个人觉得子类在继承父类对象时  会继承父类的私有属性,子类对象只是没有访问权限。
子类对象在new的时候会调用父类构造函数,这时父类构造函数中的this代表了子类对象。这时使用this给私有成员变量赋值时也是向子类私有属性赋值

作者: zhengyang    时间: 2016-7-14 16:44
继承
      不管父类中的成员是public、protected、default还是private访问权限、子类都会拥有父类中的成员,也就是说,在堆内存中的子类对象里面有一个父类对象。
     拥有并不代表可以直接访问:private成员变量,子类对象无法直接访问;default成员变量,子父类同一个包,可以直接访问,不在同一个包是不能直接访问的。其他访问权限都是可以使用子类对象直接访问父类成员。
     父类中的成员变量是静态的、还是非静态的,子类都会拥有父类中的这些成员变量。只要没有被private修饰都是可以直接调用的。

这不属于直接使用啊,你的构造方法里面默认了调用了父类的构造方法,这才使用的,就像你用
Student对象调用 set.get方法一样呗
class Student extends Person{

        /*public Student() {     //没有构造参数,系统默认添加无参构造参数
                super();                        //默认调用父类的无参构造方法
        }*/       
}


作者: 敲敲敲dm    时间: 2016-7-29 22:33
public class Demo_Extends {
        public static void main(String[] args) {
                new Son();
        }
}
        class Father{
                private int num=3;
                public  int i = 4;
                Father(){
                        System.out.println(this.num);
                }
        }
                class Son extends Father{
                       
                }
他这个this就是父类的this,你可以用代码将他分为几个简单的问题,然后理解
作者: jsong    时间: 2016-8-1 01:07
新手上路求多指教 还没学到这么多  进来一看   没有一个问题能看懂    我好方
作者: absvir    时间: 2016-8-18 12:46
你创建了子类对象,子类对象创建时自动调用父类的构造方法,父类构造方法完成this.name的赋值.
作者: absvir    时间: 2016-8-18 13:09
唐小斗 发表于 2016-6-16 09:51
首先这是可以运行的用的是Junit测试,你最后所说的“在构造方法中this.name = "ths",进行的是对这个属性n ...

name属性是父类的,但在继承关系中,你创建Student类对象的时候,Person类对象也会自动调用父类构造方法创建对象。且父类对象在子类对象的内部,所以子类可以继承父类的属性和方法。比如:{子:{父:name}},外面的大括号代表子类对象,里面的大括号代表父类对象。name这个属性在父类对象里,但因为嵌套关系的存在,那么也在子类对象里。name这个属性在父类中定义,子类从父类继承过来获得name,这种类似于嵌套的模式下我的水平只能解释成这样了——name在父类中定义,子类继承获得(即使父类属性被私有化,子类任可继承,知识无法访问)。




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