您的位置:首页 > 其它

Day3对继承和对象的一点理解

2015-04-29 10:50 169 查看
1、对继承的理解

父类是Shape,子类是Rect

Shape shape = new Rect();

Shape类里有method1,method2

Rect类里有method2 ,method3,

首先继承机制只对实例对象有效,对属性、静态方法无效

shape可以点出的方法有method1,method2,无法调用Rect类里的方法,为什么会这样呢。

可以这样理解,透过Shape类向外看,我们只能看到method1,method2,method3不在shape里能看到

并且调用shape.method2()方法时调用的是子类rect的方法(虽然这里没有Rect rect=new Rect())。

2、对象的创建问题

String str = new String("abc");

这个语句到底创建了几个对象呢,答案是2个。

 我们可以把上面这行代码分成String str、=、"abc"和new String()四部分来看待。String str只是定义了一个名为str的String类型的变量,因此它并没有创建对象;=是对变量str进行初始化,将某个对象的引用(或者叫句柄)赋值给它,显然也没有创建对象;现在只剩下new String("abc")了。那么,new String("abc")为什么又能被看成"abc"和new String()呢?我们来看一下被我们调用了的String的构造器:

  Java代码

  public String(String original) {

  //other code ..

  }

  大家都知道,我们常用的创建一个类的实例(对象)的方法有以下两种:

 使用new创建对象。

  调用Class类的newInstance方法,利用反射机制创建对象。

我们正是使用new调用了String类的上面那个构造器方法创建了一个对象,并将它的引用赋值给了str变量。同时我们注意到,被调用的构造器方法接受的参数也是一个String对象,这个对象正是"abc"。由此我们又要引入另外一种创建String对象的方式的讨论——引号内包含文本。

这种方式是String 特有的,并且它与New的方式存在很大区别

String str="prs" ,只一句就创建了一个String 对象。

让人迷惑的是String a="xx"+'YY"居然创建了三个对象!!

知道字符串池的相关知识就可以解释这个现象了。

在JAVA虚拟机(JVM)中存在着一个字符串池,其中保存着很多String对象,并且可以被共享使用,因此它提高了效率。由于String类是final的,它的值一经创建就不可改变,因此我们不用担心String对象共享而带来程序的混乱。字符串池由String类维护,我们可以调用intern()方法来访问字符串池。

  我们再回头看看String a="abc";,这行代码被执行的时候,JAVA虚拟机首先在字符串池中查找是否已经存在了值为"abc"的这么一个对象,它的判断依据是String类equals(Object obj)方法的返回值。如果有,则不再创建新的对象,直接返回已存在对象的引用;如果没有,则先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。

package com.homework.test;

public class testString {
public static void main(String[] args) {
String a=new String(new char[]{
'a','b','c','d'
});
String b = a.intern();

if(b==a){
System.out.println("b被加入字符串池中,没有新建对象");
}else{
System.out.println("b没被加入字符串池中,新建了对象");
}

}
}
运行结果为

b被加入字符串池中,没有新建对象

我们查看inter()方法有这么一段话

当调用 intern 方法时,如果池已经包含一个等于此
String
对象的字符串(用
equals(Object)
方法确定),则返回池中的字符串。否则,将此
String
对象添加到池中,并返回此
String
对象的引用。 

说了这么多,我觉得有点晕。实在不行记住了就好,在面试中可能会用到。

3、代码加载时间的问题

package com.homework3.homework3_3;

/*
* 创建一个基类,包含抽象方法print()
*/
public abstract class Base {
public abstract void print();
public Base() {
print();
}
}
package com.homework3.homework3_3;

public class Child extends Base{
int n = 5;

@Override
public void print() {
System.out.println(this.n);
}

}
package com.homework3.homework3_3;
/**
* 在创建Child对象时,首先调用的是父类的构造方法(创建父类对象?)
* 父类构造方法中Print方法被调用,打印的是n的值,而此时n虽然被定义为int型,但仍未赋值
* 所以打印的是0
* 	       5
* 当把int n修饰为static int n的时候,打印结果变为了5
* 					       	    5
* 验证了静态加载时间是在构造方法之前
* 静态代码块是在类加载时自动执行的,
* 非静态代码块在创建对象自动执行的代码,
* 不创建对象不执行该类的非静态代码块
*/
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.print();
String str="a"+"b";
String ss="ab";
System.out.println(str.intern().equals(ss.intern()));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息