您的位置:首页 > 编程语言 > Java开发

Thinking in java 学习笔记(三)

2016-11-21 15:56 197 查看
7.2 动态绑定 程序在运行时动态绑定运行的代码
重写:在基础类中构造方法接口,衍生类根据实际情况对方法进行重写。基础类 A=new 衍生类(); A.方法();参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。返回的类型必须一直与被重写的方法的返回类型相同,否则不能称其为重写而是重载。访问修饰符的限制一定要大于被重写方法的访问修饰符(public>protected>default>private)。重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:父类的一个方法申明了一个检查异常IOException,在重写这个方法是就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。
重载:必须具有不同的参数列表;可以有不同的返回类型,只要参数列表不同就可以了;可以有不同的访问修饰符;可以抛出不同的异常;
7.4 抽象类和方法 如果一个类中包含一个或多个抽象方法,则这个类必须为抽象类;如果一个类继承这个抽象类,则必须全部实现基础抽象类的抽象方法,否则衍生类也要声明为抽象类。抽象方法没有实现体: abstract void f();
如果一个类没有抽象方法,也可以声明为抽象类,禁止该类的所有实例。
7.5 接口 "纯"抽象类 允许创建一个类的基本形式:方法名、自变量类别、返回类型,但不规定方法主体。可以包含数据成员,默认为static和final。接口可以继承接口;类需要实现接口所有的方法,否则需要声明为抽象类
接口中声明的方法可以用public或者“友好的”(无修饰符),但是它们会默认为public。所有在实现接口方法时,必须定义成public。
使用接口最重要的原因:能够上溯多个基础类(接口);和抽象类一样,防止客户程序员制作这个类的一个对象,以及规定它仅仅是个接口。
使用接口同时包含抽象类和接口的好处,假如想创建的基础类没有任何方法定义或者成员变量(接口中可以定义成员变量),最好选用接口。在必须使用方法定义或成员变量时,才考虑使用抽象类。
类只能继承一个基础类,接口可以继承多个接口;类可以继承一个基础类,实现多个接口。
接口中所有的字段都是static和final属性,可以用来常数分组(java命名规则:拥有固定标识符的static final基础数据类型,都采用大写字母,用下划线分隔单个标识符里的多个单词)
接口中的字段会自动具有public属性,无需专门指定。
7.6 内部类 类内部的类 除外部类|非static方法内部|之外|的任何地方生成内部类的一个对象,必须将那个对象的类型设置为:外部类名.内部类名
内部类可以使用private和protected修饰 内部类通过继承基类或实现接口,使用private或protected可以完全禁止其他人依赖类型编码,并将实施细节完全隐藏起来。
方法和作用域中的内部类:
1.实现某种形式的接口,使自己能创建和返回一个句柄。2.创建类辅助解决复杂问题,同时不愿意公开。

public class A {
       public face a(){
               class add implements facetest{
                     public void f() {
                        ....;
                     }

              }
              return new add();
           };
       }
interface face{
       void f();
       }

public class B{
       public face a(){
              return new face() {
                     public void f() {
                      ...;
                     }
              };
              }
       }
interface facetest{
       void f();
       }

匿名内部类不能有构造函数,因为没有名字付给构造器。
使用外部对象来定义内部类时,外部对象需要定义成final。
7.6.2内部类使用初始化模块可以对内部类进行构造,相当于内部类的构造器,初始化模块不能进行重载,所有只能表示一个构造器。
7.6.3内部类拥有封装对象(外部类的成员对象)的全部访问权限,包括private修饰的对象。
7.6.4static内部类 内部类的对象默认持有创建它的封装类的一个对象句柄。static内部类:1.创建一个static内部类,不需要一个外部对象。2.不能从static内部类中访问外部类对象。
由于static成员只能位于一个类的外部级别,所有内部类不可拥有static数据或static内部类。static内部类可以拥有static数据或static内部类。
7.6.5引用外部类对象 内部类引用外部类的成员,通过外部类名.this.外部类成员名的形式。
在其他类中,使用一个内部类,必须使用一个外部类的对象生成内部类的一个对象:外部类名.内部类名 内部类=外部类.new 内部类名;如果是static内部类,则不需要。
7.6.6 从内部类继承 其他类在继承一个内部类时,内部类的构造器必须和外部类的一个实例对象联系在一起,衍生类只是对内部类进行了继承,在衍生类的构造器中必须传递一个外部类的实例对象。

必须在构建器中采用下述语法:
enclosingClassHandle.super();

class TestClass{
       class InClass{}
}
public class ExtInClass extends TestClass.InClass{
public ExtInClass(TestClass tc) {
       tc.super();
}
}

7.6.7 当继承外部类时,内部类不会被覆盖,当“显式”的继承内部类时,可调用内部类被重写的方法。
7.6.9 为什么使用内部类:控制框架 内部类允许我们:1.在单独一个类里表达一个控制框架应用的全部实施细节,从而完整地封装与那个实施有关的所有东西。内部类用于表达多种不同类型的action(),它们用于解决实际问题。可以使用private内部类,所有实施细节会完全隐藏起来,可以安全地修改。2.内部类使我们具体的实施变得更加巧妙,因为能方便地访问外部类的任何成员。
7.7.1 构造器调用顺序 1.调用基础类构造器,不断
96b1
循环,知道最深一层。2.按声明顺序调用成员初始化模块。3.调用衍生类构造器。
7.7.2 finalize()在类进行析构时,finalize函数不一定运行,可以使用System.runFinalizersOnExit(true);强制之行。子类在重写finalize()时,必须调用父类的finalize()函数,否则父类的finalize()不会进行初始化,父类不会的finalize()不会执行(父类未“显式”new,只是在new
子类的时候对父类进行了构造函数的调用,如果new 父类,finalize()还会执行)。
析构顺序与构造顺序相反。
7.7.3 在构造子类时,需要先构造父类,当父类的构造函数中调用抽象函数等时,父类会调用子类的抽象函数函数实现方法。
初始化顺序:1.加载,分配对称存储空间,初始化对象值为二进制0。2.调用父类构造器(构造函数中调用了抽象方法),被子类重写的抽象方法会被父类构造函数调用,子类成员变量此时还是默认二进制0,如果发生调用,则将默认二进制0传入。3.按照声明顺序初始化成员变量。4.调用子类构造函数。
设计构造器有效原则:使用尽可能简单方法使对象进入就绪状态;如果可能,避免调用任何方法。
7.8 继承和合成 程序设计时首先选择合成,合成可以动态选择类型(运行期通过重新绑定句柄,可以改变行为),继承在编译期需要明确知道类型(运行期不能改变继承的形式)。设计准则:用继承表达行为间的差异,并用成员变量(合成)表达状态的变化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: