第六章 面向对象(下)
abstract和interface分别定义抽象类和接口。抽象类主要作为多个类的模板,接口定义了多类应该遵守的规范。
6.1 增强的包装类
- 自动装箱:把一个基本类型变量直接赋给对应的包装类变量;
- final关键字可修饰类、变量、方法,表示类、方法、变量不可改变。
- final修饰的成员变量必须由程序员显示的指定初始值。
- 建议尽量避免在final变量显示初始化之前访问它。
- final修饰基本类型变量时,不能对基本类型变量重新赋值;对引用类型变量,保存的仅仅是一个引用,final只保证引用的地址不变,但这个对象可以改变。
- java编译器会将final变量当成“宏变量”处理。
- 对于final实例变量,只有在定义该变量时指定初始值才会有“宏变量”的效果。
- final修饰的方法不可被重写,可以被重载。
- final修饰的类不可以有子类。
- 不可变类*:创建该类的实例后,该实例的实例变量是不可改变的。
- 创建不可变类规则:使用private和final修饰;提供带参数构造器;仅提供getter方法;如果有必要,重写hashCode()和equals()方法。(注意引用类型的成员变量)
- 缓存实例的不可变类,某个对象需要频繁的重复使用就缓存。(P185没太懂)
- 使用abstract修饰符定义。
- 规则:必须使用abstract修饰,抽象方法不能有方法体;抽象类不能被实例化;抽象类的构造器不能创建实例,主要用于被其子类调用;含有抽象方法的类只能被定义成抽象类。
- 抽象类“有得有失”:“得”抽象类可以包含抽象方法;“失”抽象类不能用于创建实例。
- 抽象方法和空方法体不是一个概念。
- final修饰的类不能被继承,修饰的方法不能被重写。因此final和abstract永远不能同时使用。
- abstract不能修饰成员变量,局部变量,构造器,(抽象类里定义的构造器只能是普通构造器)
- static和abstract不能同时修饰某个方法,即没有所谓的类抽象方法。(但它们可以同时修饰内部类)
- 抽象类是从多个具体类中抽象出来的父类吗,具有更高层次的抽象。(模板模式)
- 模式一:父类提供了多个子类的通用方法,并把一个或多个方法留给其子类实现。
- 模式二:父类的普通方法依赖于一个抽象方法,而抽象方法则推迟到子类中实现。
- 接口体现的是规范和现实分离的设计哲学。
- 只有在相同包结构下才可以访问该接口。
- 一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类。
- 接口里定义的内部类、内部接口、内部枚举默认采用public static两个修饰符,不管定义时是否指定这两个修饰符,系统会自动使用public static对它们进行修饰。
- 接口的默认方法其实就是实例方法。
- 从某个角度来看,接口可被当成一个特殊的类。
- 接口完全支持多继承。
- 接口的作用:定义变量,用于进行强制类型转换;调用接口中定义的常量;被其他类实现。
- 继承使用extends关键字,实现使用implements关键字。
- 实现接口和继承父类相似,一样可以获得所实现接口里定义的常量、方法。
- 一个类实现了一个或多个接口之后,这个类必须完全实现这些接口里所定义的全部抽象方法(重写这些抽象方法);否则该类将保留从父接口继承到的抽象方法,该类也必须定义成抽象类。
- 一个类实现某个接口时,该类将会获得接口中定义的常量、方法等,因此可以把实现接口理解为一种特殊的继承。
- 相同点:都不能被实例化,都位于继承树的顶端,用于被其他类实现和继承;都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。
- 接口:体现的是一种规范,类似于整个系统的“总纲”。
- 抽象类:体现的是一种模板式的设计,作为系统中多个子类的共同父类。
- 设计模式:对经常出现的软件设计问题的成熟解决方案。(对特定问题的一种惯性思维,理解需以足够的代码量为基础)
- 简单工厂模式:定义一个工厂类,他可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。(需要什么,只需要传入一个正确的参数,就可以获取所需要的对象,而无需知道其实现过程)
- 命令模式:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志。以及支持可撤销的操作。(就是将一系列的请求命令封装起来,不直接调用真正执行者的方法,这样比较好扩展)
- 定义在其他类内部的类就称为内部类(也叫嵌套类)
- 作用:提供了更好的封装,不允许同一包中的其他类访问该类;内部类成员可以直接访问外部类的私有数据;匿名内部类适合用于创建那些仅需使用一次的类;
- 内部类和外部类的区别:内部类多了三个修饰符:private、protected、static;非静态内部类不能拥有静态成员。
- 使用static修饰的成员内部类是静态内部类,没有使用的是非静态内部类。
- 在外部类里使用非静态内部类时,与使用普通类并没有太大的区别。
- 编译程序,生成两个class文件,Cow.class、Cow$CowLeg.class。
- 使用this、外部类名.this 来区分外部内部成员变量。
- 如果外部类需要访问非静态内部类的成员,必须显式创建非静态内部类对象来调用访问其实例成员。
- 当调用非静态内部类的实例方法时,必须有一个非静态内部类实例,非静态内部类实例必须寄生在外部类实例里。
- 非静态内部类里不可以有今天初始化块,可以有普通初始化块。
- 使用static修饰一个内部类,这个内部类就属于外部类本身(不属于外部类的某个对象)。因此使用static修饰的内部类被称为类内部类,也称为静态内部类。
- 静态内部类对象寄生在外部类的类本身中(不是寄生在外部类的实例中)
- 在外部类内部使用内部类:与普通类没有太大区别(不要再外部类的静态成员中使用非静态内部类,以为静态成员不能访问非静态成员)
- 在外部类以外使用非静态内部类:内部类不能使用private访问控制权限;
在外部类以外的地方定义内部类:
在外部类以外的地方创建非静态内部类实例: - 非静态内部类的构造器必须使用外部类对象来调用。
6.4 final修饰符
编译器在编译阶段就确定s2为“疯狂java”,系统会让s2直接指向常量池中的缓存的“疯狂java”字符串,因此s1 == s2;对c3,值是由c1c2连接运算后得到的,c1c2只是普通变量,编译时不会执行“宏替换”,因此编译器无法在编译时确定c3 的值,c3无法指向“疯狂java”字符串,所以false;(将c1c2使用final修饰,输出true)。
6.5 抽象类
6.5.1 抽象方法和抽象类
6.5.2 抽象类的作用
6.6 接口
将这种抽象进行得更彻底,则可以提炼出一种更加特殊的“抽象类”——接口(interface)
6.6.1 接口的概念和定义
6.6.3 接口的继承
6.6.5 接口和抽象类
6.6.6 面向接口编程
6.7 内部类
6.7.1 非静态内部类
6.7.2 静态内部类
6.7.3 使用内部类
class Out{ class In{//内部类 public In(String msg){ System.out.println(msg); } }}public class CreateInnerInstance声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!