第6章 面向对象(下)
6.1Java8增强的包装类:
Java有8个基本类型:byte, short, int, long, float, double,char,
Boolean,这8个基本类型不能当成对象使用,而且也不能接受null值。
为了解决上面的问题,Java为8个基本类型提供了对应的包装类——可将他们包装成对象。
- byte - Byte
- short - Short
- int - Integer
- long - Long
- float - Float
- double - Double
- char - Character
- boolean - Boolean
▲自动装箱:基本类型的值可以自动当成包装类的实例使用。
▲自动拆箱:包装类的实例可以自动当成基本类型的值使用。
【建议】:以后做项目是,通常来说建议使用包装类来声明变量。好处是:反正基本类型能做的,它都可以做;它还可以当成对象使用,还可以接受null。
▲包装类的方法:parseXx
可将字符串转成对应的基本类型值。
NumberFormatException:要转的字符串不符合数值格式,将会引发该异常。
6.2处理对象
★Object的两个常用方法:
Obkect是一切类的父类,因此Java对象都可以调用Object类所提供的方法。
▲toString() 方法
当你输出一个对象,或将一个对象与字符串进行连接时,Java默认调用该对象的toString()方法将该对象自动转成字符串。很多时候,都会重写Object的toString()方法。toString()也叫“自我描述”方法。
▲equals() 方法
判断两个引用变量时,要求两个变量指向同一个对象才返回true。
Object提供的equals方法,判断两个引用变量相等的标准,与的判断标准完全一样。
如果要判断两个对象是否相等,很多时候应该使用equals
——此时必须要重写equals()方法:重写该方法,就是告诉系统,两个对象相等的业务标准。
6.3类成员
▲static并不是静态的意思。static是类的意思,有static的成员属于类成员,没有static的成员属于实例成员。
static是否可以修饰局部变量 —— 局部变量不属于类成员,因此不能用static修饰。
static是否可以修饰外部类 —— 外部类不属于成员,因此不能用static修饰。
static可修饰的类成员:成员变量、方法、初始化块、内部类
▲static成员(成员变量、方法、初始化块、内部类) - 属于类成员。
所有类成员,都只能用类名调用!
Java语法是不好,允许通过对象来调用类成员,其实没有意义!
▲static考点:
static成员不能访问非static成员;
非static成员可以访问static成员!
static成员(4种)不能访问非static成员(5种多一个枚举类)
▲单例模式(Singleton):
设计模式:对于一批经常出现的设计场景,前任总结出来的比较成功的设计——这就是设计模式。后面的人就应该学习、并模仿,从而提高我们的代码质量。
单例模式:在某些场景下,某些类只需要(只能)创建一个实例。此时就应该采用单例模式。
如何设计单例模式?
- 隐藏构造器——避免被创建实例。
- 暴露一个static方法,该方法用于创建实例。该方法还需要保证,该类只会产生一个实例。
6.4 final修饰符
可以修饰变量(各种变量)、方法、类。
final与abstract是互斥的:永远不能同时出现!
▲final修饰变量:该变量被赋值之后,不能被重新赋值!
final修饰的变量【必须】被赋值,且只能赋值【一次】。
▲final修饰成员变量:
非final的成员变量,程序可以不显式指定初值,系统会为之分配默认初始值。
final的成员变量,程序员必须显示指定初始值。
●final实例变量,必须显式指定初始值。只能在以下3个位置的其中之一指定:
-定义时指定初始值
-实例初始化块
-每个构造器显式指定一次初始值。
上面3个位置的本质其实只有一个:构造器。
●final类变量,必须显式指定初始值。只能在以下2个位置的其中之一指定:
-定义时指定初始值。
-类初始化块。
(注意:final修饰的类变量不能用构造器赋初始值)
上面2个位置的本质其实只有一个:类初始化块。
▲final修饰局部变量:
非final的局部变量,程序员必须显示指定初始值,然后才能使用。
final的局部变量,程序员必须显示指定初始值,然后才能使用。
final局部变量不能被重新赋值。
▲final修饰的引用类型的变量。
final值保证该引用变量本身不会被重新赋值,该变量所引用的对象完全可以被修改!
▲▲final修试的“宏替换”的变量。
如果一个变量满足以下3个条件:
-变量有final修试。
-声明变量时指定了初始值。
-变量的初始值可以在编译时确定(初始值的表达式中没有变量、方法调用等)
这个变量就会消失,所有出现该变量的地方,在编译时就会替换成该变量的值。
▲final修饰方法:
表明该方法不允许被子类重写。
——该方法可以被重载,也可以被子类调用!
【备注】:private方法已经被隐藏在该类的内部,子类无法访问该方法,因此不可能被重写。final修饰private方法纯属多余!但Java是允许的!
▲final修饰类
表明该类不能派生子类!
jdk里很多类都是final:String、Math、System
Object是否为final?一定不是final的!
★abstract(抽象)
它只能修饰2个东西:方法和类。抽象方法、抽象类。
abstract和final是互斥的,永远不能同时出现!
▲抽象类:有得有失
抽象类与普通类的区别只有4个字:有得有失。
-有得:得到一个新功能:抽象类可拥有抽象方法。
-有失:抽象类失去了一个功能:创建对象。
抽象类的主要作用:派生子类;
子类构造器一定要调用父类构造器一次,因此抽象类必须有构造器。
▲抽象方法:只能有方法签名,没有方法体的方法。
抽象方法,一定要交给子类去实现,否则不能用!
▲抽象类的作用:
1、定义变量,只能用它的子类的实例:向上转型。
2、调用类方法和类变量。
3、派生子类——主要目的。
▲抽象类派生子类:
【推论规则】:子类要么重写抽象父类中的所有抽象方法,要么子类也只能是抽象的。
6.6接口
接口相当于一种彻底抽象的类。
接口体现的是一种规范——要暴露出来供大家遵守,所以接口里所有的东西都是public修饰,不挂你写还是不写,始终有public修饰,通常都不写。
定义接口:
[修饰符] interface 接口名 extends 父接口1,父接口2,...
{
//成员变量。只有常量,总会添加public、statcit、final修饰。通常程序员都不写。(静态常量)
//抽象方法。Java8之后,类方法、默认方法(抽象方法体)。只能是抽象实例方法、类方法、默认方法或私有方法
//内部类 包括内部接口、枚举
}
系统添加 | |||
---|---|---|---|
常量 | public | static | final |
抽象实例方法 | public | abstract | |
默认方法 | public | ||
类方法 | public |
从上面可以推论:接口没有构造函数和初始化块,因为接口不创建对象。
接口是多继承的。
修饰符:public。接口是彻底抽象,不能有final;接口已经够抽象,因此不需要abstract修饰。
接口名:命名规范基本等同于类名。
接口一般推荐使用形容词。添加able就是形容词。
一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类。
▲接口的用处
- 定义变量,只能用实现类的实例来赋值(向上转型)
- 调用类方法或类变量。
- 派生实现类(子类)
类实现接口语法:
[修饰符] class 类名 extends 父类 implements 接口1,接口2,...
{
类体部分
}
- 一个类实现了一个或多个接口之后,必须重写接口中的抽象方法,否则集成到的抽象方法将保留,该类也要定义为抽象类。
- 实现接口的方法时,必须使用public访问控制符,因为接口里面的方法是public的,所以重写的方法要遵循“两同两小一大”。
★内部类
放在其他类的类体里面定义的类,该类就属于内部类,包含内部类就被称为外部类。
内部类与顶层类的语法区别:
- 内部类可以多如下修饰符:static、private、protected
- 非静态内部类不能拥有静态成员——除非是常量。
- 内部类可以直接访问外部类私有成员,但静态内部类不能访问外部类的非静态成员!
★内部类的意义:当某个类的实例必须要衣服另一个类的存在而存在,此时即可使用内部类。内部类可以提供更好的封装。
内部类的文件名:外部类$内部类.class
★区分变量
内部类直接访问外部类的成员变量。单如果内部类的方法、内部类的成员变量与外部类的成员你变量重名时,就需要进行如下区分:
外部类.this.实力成员
★使用内部类
★在外部类的里面使用内部类
基本上使用内部类与使用其他类没什么区别——唯一注意:静态成员不能使用费静态内部类创建实例。
★在外部类的外面使用静态内部类
该内部类一定不能用private修饰!
在外部类的外面使用静态内部类——只要把外部类当成静态内部类的包名即可。
- 声明变量:
外部类.静态内部类 变量名; - 创建对象:
new 外部类.静态内部类的构造器(参数); - 调用类方法或访问类变量:
外部类.静态内部类.类变量;
外部类.静态内部类.类方法(参数); - 派生子类:
extends 外部类.静态内部类