面向对象(下)
提纲
- 包装类
- equals、toString方法
- static、finally关键字
- abstract关键字和抽象类
- 接口的定义与作用
- 内部类的作用
- 枚举类
- JAR包
基本数据类型的包装类
- 八大数据类型的包装类分别是:Byte、Short、Integer、Long、Character、Float、Double、Boolean。把基本数据类型变量包装类实例是通过对应包装类的valueOf实现的,不仅如此,8个包装类中除了Character之外,还可以通过传入一个字符串参数来构建包装类对象
- 如果希望获得包装类对象中包装的基本类型变量,则可以使用包装类提供的xxxValue()实例方法
自动装箱与自动拆箱
- JDK还提供了自动装箱和自动拆箱。自动装箱就是把一个基本类型的变量直接赋给对应的包装类变量,自动拆箱则与之相反
- 包装类还可以实现基本类型变量和字符串之间的转换,除了Character之外的所有包装类都提供了一个parseXxx(String s)静态方法
- 如果将基本类型转换为字符串,只需在后面加+“ ”进行连接运算
Java 7对包装类的增强
- Java 7为所有包装类增加一个新方法:compare(x,y)的方法。该方法用于比较两个包装类实例,当x>y,返回大于0的数;当x==y,放回0;否则返回小于0的数;
对象的方法
- 打印对象和toString方法:toString方法是系统将会输出该对象的“自我描述”信息,用以告诉外界对象具有的状态信息
- Object类提供的toString方法总是放回该对象实现类的类名+@+hashCode值
- ==和equals比较运算符:==要求两个引用变量指向同一个对象才会返回true。equals方法则允许用户提供自定义的相等规则
- Obect类提供的equals方法判断两个对象相等的标准与==完全相同。因此开发者通常需要重写equals方法
类成员
- 在Java类里只能包含Field,方法,构造器,初始化块,内部类(接口、枚举)等5种成员用static修饰的类成员属于类成员,类Field既可以通过类来访问,也可以通过类的对象来访问。当通过对象来访问类属性时,系统会在底层转化为通过该类来访问类属性
类成员规则
- 类成员并不是属于实例,它是属于类本身的。只要类存在,类成员就存在
- 即使通过null对象来访问类成员,程序也不会引发NullPointerExcepton
- 类成员不能访问实例成员
单例类
- 如果一个类始终只能创建一个对象,称为单例类。须符合以下几个条件:
- 1.我们把该类的构造器使用Private修饰,从而把该类的所有构造器隐藏起来
- 2.则需要提供一个public方法作为该类的访问点,用于创建该类的对象,且必须使用static修饰
- 该类还必须缓存已经创建对象,必须用static修饰
final变量
- final修饰变量时,表示该变量一旦获得初始值之外就不可被改变
- final既可修饰成员变量,也可以修饰局部变量
final修饰成员变量
- 成员变量是随类的初始化或对象初始化而初始化的。final修饰的成员变量必须由程序员指定初始值
- 对于类属性而言,要么在静态初始化中初始化,要么在声明该属性时初始化
- 对于实例属性,要么在普通初始化块中指定初始值。要么在定义时、或构造器中指定初始值
final修饰局部变量
- 使用final修饰局部变量时既可以在定义时指定默认值,也可以不指定默认值
- 给局部变量赋初始值,只能一次,不能重复
final修饰基本类型和引用类型
- 当使用final修饰基本数据类型变时,不能对其重新赋值,不能被改变
- 但对引用类型的变量而言,它仅仅保存的是一个引用,final只能保证他的地址不变,但不能保证对象,所以引用类型完全可以改变他的对象
可执行“宏替换”的final变量
- 对一个final变量来说,不管它是类变量、实例变量,还是局部变量,只要该变量满足3个条件,这个fianl变量就不再是一个变量,而是相当于一个直接量
- 使用fianl修饰符修饰
- 在定义fianl变量时指定了初始值
- 该初始值可以在编译时就被确定下来
final方法
- final修饰的方法不可以被重写
- final修饰的方法仅仅是不能重写,但它完全可以被重载
final类
- fianl修饰的类不可以被继承
不可变的类
- 不可变得类要满足以下几个条件:
- 使用private和fianl修饰符来修饰该类得属性
- 提供带参数得构造器,用于根据传入参数来初始化类得属性
- 仅为该类的属性提供getter方法,不要为该类的属性提供setter方法,因为普通方法无法修改final修饰的属性
- 如有必要,重写Object类中hashCode和equals
- 缓存实例的不可变类:如果程序经常需要使用不可变的实例,则可对实例进行缓存
抽象方法和抽象类
- 抽象方法和类都必须使用abstract来修饰,有抽象方法的类只能定义成抽象类,抽象里也可以没有抽象方法。
- 抽象类不能被实例化,可以通过其子类给他赋值,普通类里有的抽象里也有,定义抽象方法只需在普通方法上增加abstract修饰符,并把普通方法的方法体(也就是方法后花括号括起来的部分)全部去掉,并在方法后增加分号即可
抽象类的特征
- 抽象类的特征:有得有失,得到了新能力,可以拥有抽象方法;失去了创建对象的能力
抽象的作用
- 抽象类代表了一种未完成的类设计,它体现的是一种模板
- 抽象类与模板模式
接口的概念
- 接口定义的是多个类共同的行为规范,这些行为是与外部交流的通道,这就是意味着接口里通常是定义一组公用的方法
- 接口体现了规范与实现分离的设计
接口的定义
- 和类定义不同,定义接口不再用class关键字,而是使用interface关键字。语法如下:
- 【修饰符】interface接口名extends父接口1,父接口2…
- {
- 零个到多个常量定义…
- 零个到多个抽象方法定义…
- 零个到多个内部类、接口、枚举定义…
- 零个到多个私有方法、默认方法或类方法定义…
- }
接口里的成分
- 在定义接口时,接口里可以包含成员变量(只能是常量),方法(只能是抽象实例方法、类方法、默认方法或私有方法),内部类(包括内部接口、枚举类)
- 常量都是public static final修饰
- 抽象方法都是:public abstrac修饰
- 内部的类:pubic static
接口的继承
- 接口的继承和类基层不一样,接口完全支持多继承,子接口扩展某个父接口将会获得父接口的所有抽象方法,常量属性,内部类和枚举类定义
使用接口
- 接口可以用于声明引用类型的变量,但接口不能用于创建实例
- 当使用接口来声明引用类型的变量时,这个引用类型的变量必须引用到其实贤类的对象
- 一个类可以实现一个或多个接口没继承使用extends关键字,实现接口则使用implements关键字
实现接口
- 一个类实现了一个或多个接口之后,这个类必须完全实现这些接口里所定义的全部抽象方法(也就是重写这些抽象方法);
- 否则,该类将保留从父接口哪里继承到的抽象方法,该类也必须定义成抽象类
接口和抽象类的相似性
- 接口和抽象都不能被实例化,它们都位于继承数的顶端你,用于被其他类实现和继承
- 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法
接口与抽象类的区别
- 接口里只能包含抽象方法、静态方法、默认方法和私有方法,不能为普通方法提供方法实现;抽象类则完全可以包含普通方法。
- 接口里只能定义静态常量,不能定义 普通成员变量;抽象类里则既可以定义普通成员变量,也可以定义静态常量
- 接口里不包含构造器:抽象类可以包含构造器,抽象类的构造器并不是用于创建对象,而是让其子类调用这些构造器来完成属于抽象类的初始化操作
- 接口里不包含初始化块;但抽象类则完全可以包含初始化块
- 一个类最多只能有一个直接父类,包含抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Java单继承的不足
面向接口编程
- 接口体现了规范与实现分离的原则。充分利用接口可以很好地提高系统的可扩展性和可维护性
- 接口与简单工厂模式、命令模式等
内部类
- 我们把一个类放在另一个类的内部定义,这个定义在其他类内部的类就被称为内部类,有的也叫嵌套类,包含内部类的类也被称为外部类有的宿主类
- 内部类提供了更好的封装,内部类成员可以直接访问外部被当成其他外部类成员。
- 匿名内部类适合用于创建哪些仅需要一次使用的类。
非静态内部类
- 定义内部类非常简单,只要把一个类放在另一类内部定义即可。
- 当在非静态内部类的方法内访问某个变量时,系统优先在该方法内查找是否存在该名字的局部变量,如果存在改名字的局部变量,就使用该变量,如果不存在,则到该方法所在的内部类中查找是否存在该名字的属性,如果存在则使用该属性
- 总之,第一步先找局部变量,第二步,内部类的属性,第三步。外部类的属性。
静态内部类
- 如果用static修饰一个内部类,称为静态内部类。
- 静态内部类可以包含静态成员,也可以包含非静态成员。所以静态内部类不能访问外部类的实例成员,只能访问外部类的类成员
- 静态内部类的对象寄存在外部类里,非静态内部类的对象寄存在外部类实例里
今天先更到这里吧,这一篇大概还有一半左右,明天补上。