面向对象2

一、关于接口interfaceObject类的关系

其实这个问题讨论起来没什么意义,可能在实际开发中的用处并不是很大。

public interface T
 {
         void itMethod();
}
public class C implements T {
         public void itMethod() {
                   System.out.println("override interface method!!");
         }
         public void clsMethod(){
                   System.out.println("class method!!");
         }
}
public class Demo {
         public static void main(String[] args) {
                   T it=new C ();
                   it.it();
                   it.clsMethod();//此行会报错;这是大家都知道的,因为接口没有clsMethod方法
                   System.out.println(it.toString());//接口中也没有看到toString方法,但此处没有报错。
                   Class cs= T.class;
                   Class sc=cs.getSuperclass();            //sc引用为空                   
         }
}

       对于这种情况,如果上述引用型变量it的类型(T)是某一个类的话,大家也就很容易理解,因为所有类的根类都是Object类,Object类中的方法也就自然的能被其直接或间接子类继承,根据多态的原理,it调用Object类中的方法是不会出错的,因为TC类都直接或间接地继承了Object中的方法。

        但重点是,如果it的类型T不是具体的类而是接口时,那么它还会有Object中的方法和属性么?有很多人都认为接口的直接或间接父类也是Object,但真的是这样的么,没错我们常说接口是一个特殊的类,如果是类的话,那么它的根类不就是Object么?事实上,我个人认为可以把接口看作是特殊的类,但它并不是Oject类的子类(如果有的话sc就不会为空),接口interfaceclass应该属于同一级别的概念,他们之间是不存在从属关系的,我们通常定义地接口是没有继承Object类的。但是从上面的代码中,我们也看到了我们使用T类型的引用去调用了C类(实现了T接口)中的toString(),我们都很清楚如果T中没有toString()的话,我们使用T类型的引用去调用实现类中的toString()方法在编译的时候是通不过的,但现在编译器确实没有报错,这种现象该如何解释呢?是不是编译器对这种情况进行了特殊对待?

实际上在Sun的官方文档TJLSThe Java Language Specification)就有相关说明:

其中第99.2节关于接口有这么一段话:

         If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless a method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.

  它大概意思是说当一个接口没有直接extends superinterfaces时,那么再该接口中就会隐含定义了一套与Object类中的方法签名完全相同的方法,所以,我们在程序中调用接口的那些与Object中具有相同签名的方法时,编译器不会报错!

  这段描述对我很有帮助,说了这么多,只是想让大家在空闲时间来考虑JAVA的设计思路和理念,巩固和加深对它的理解。以上所有的均为个人看法,仅供参考,不对之处还望指出,大家共同研究讨论。

 二、关于字符串两种创建方式的总结和说明

Java运行时会维护一个String PoolString池),JavaDoc翻译很模糊字符串缓冲区String池用来存放运行时中产生的各种字符串,并且池中的字符串的内容不重复。

1.采用字面值方式赋值:String s =“hello”;

1)   查找 String Pool中是否存在“hello”这个对象,如果不存在,则在 String Pool中创建一个“hello”对象,然后将 String  Pool中的这个“hello”对象的地址返回来,赋给引用变量 s,这样 s会指向 String Pool 中的这个“hello”字符串对象

2)   如果存在,则不创建任何对象,直接将 String Pool中的这个“hello”对象地址返回来,赋给 s引用。

2.采用new的方式:String s = new String(“hello”);

1)   首先在 String Pool中查找有没有“hello”这个字符串对象,如果有,则不在 String Pool中再去创建“hello”这个对象了,直接在堆中(heap)中创建一个“hello”字符串对象,然后将堆中的这个“hello”对象的地址返回来,赋给 s 引用,导致 s 指向了堆中创建的这个“hello”字符串对象。

2)      如果没有,则首先在 String Pool中创建一个“hello“对象,然后再在堆中(heap)创建一个”hello“对象,然后将堆中的这个”hello“对象的地址返回来,赋给 s 引用,导致 s 指向了堆中所创建的这个”hello“对象。

 以上两种方式比较常见,而且区别较大,所以只是比较这两种方式,至于其他方式在此不再做过多说明。

对于字面值方式还有如下例子,感兴趣的可以研究研究:

package testPackage;
class Test {
    public static void main(String[] args) {
        String hello = "Hello", lo = "lo";
        System.out.print((hello == "Hello") + " ");
        System.out.print((Other.hello == hello) + " ");
        System.out.print((other.Other.hello == hello) + " ");
        System.out.print((hello == ("Hel"+"lo")) + " ");
        System.out.print((hello == ("Hel"+lo)) + " ");
        System.out.println(hello == ("Hel"+lo).intern());
    }
}
class Other { 
                   static String hello = "Hello";
 }

package other;
public class Other {
                   public static String hello = "Hello";
 }

result:true true true true false true

有关字符串的用法和其他说明也可参照:http://lavasoft.blog.51cto.com/62575/80034/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值