java知识进阶
基础知识回顾
定义类
定义类:
格式:修饰符 class 类名{
}
注意:1.类名的首字母建议大写。满足驼峰模式。 StudentNameCode
2.一个Java代码文件中可以定义多个类。但是按照规范还是建议一个Java文件定义一个类。
3.一个Java代码文件中,只能有一个类是用public修饰的,
而且public修饰的类名必须成为当前Java代码的文件名称。
类中的成分
类中的成分:有且仅有五大成分(五大金刚)
修饰符 class 类名{
// 1.成员变量(Field): 描述类或者对象的属性信息的。
// 2.成员方法(Method): 描述类或者对象的行为信息的。
// 3.构造器(Constructor): 初始化一个对象返回。
// 4.代码块
// 5.内部类
}
类中有且仅有这五种成分,否则代码报错!
构造器
构造器:
格式:修饰符 类名(形参列表){
}
作用:初始化类的一个对象返回。
构造器的分类:无参数构造器,有参数构造器。
构造器的注意点:一个类默认自带一个无参数构造器,但是如果写了有参数构造器那么
默认的无参数构造器就消失了,此时如果还需要用无参数构造器就需要自己从新写一个。
构造器初始化对象的格式:
类名 对象名称 = new 构造器;
Student s = new Student();
无参数构造器的作用:初始化一个类的对象(使用对象的默认值初始化)返回。
有参数构造器的作用:初始化一个类的对象(可以在初始化对象的时候为对象赋值)返回。
面向对象三大特性
面向对象的三大特征:封装,继承,多态。
是Java语言的风格。是我们在开发中必须遵循的,即使毫无意义,代码还是要按照这个风格写!!
封装的作用:
1.可以提高安全性。
2.可以实现代码的组件化。
封装的规范:
1.建议成员变量都私有:用private修饰。
private修饰的方法,成员变量,构造器等只能在本类被直接访问。
2.提供成套的getter+setter方法暴露成员变量的取值和赋值。
public修饰符,是公开的意义。
小结:
封装的核心思想:合理隐藏,合理暴露。
封装已经成为Java代码的风格,即使代码毫无意义,还是要按照封装的规范写代码。
成员变量私有,提供getter+setter方法。
static关键字
概述
目标:static关键字的概述。(重点)
引入:
我们之前定义了很多成员变量(name , age , sex)
其实我们只写了一份,但是发现每个对象都可以用,就说明
Java中这些成员变量或者方法是存在所属性的。
有些是属于对象的,有些是属于类本身的。
Java是通过成员变量是否有static修饰来区分是类的还是属于对象的。
static == 静态 == 修饰的成员(方法和成员变量)属于类本身的。
按照有无static修饰,成员变量和方法可以分为:
成员变量:
(1)静态成员变量(类变量):
有static修饰的成员变量称为静态成员变量也叫类变量,属于类本身的,
直接用类名访问即可。
(2)实例成员变量
无static修饰的成员变量称为实例成员变量,属于类的每个对象的,
必须用类的对象来访问。
成员方法:
(1)静态方法
有static修饰的成员方法称为静态方法也叫类方法,属于类本身的,
直接用类名访问即可。
(2)实例方法
无static修饰的成员方法称为实例方法,
属于类的每个对象的,必须用类的对象来访问。
小结:
成员变量有2种
-- 有static修饰的属于类叫静态成员变量,与类一起加载一次,直接用类名调用即可。
-- 无static修饰的属于类的每个对象的叫实例成员变量,
与类的对象一起加载,对象有多少个,实例成员变量就加载多少份。必须用类的对象调用。
成员方法有2种:
-- 有static修饰的属于类叫静态方法,直接用类名调用即可。
-- 无static修饰的属于类的每个对象的叫实例方法,必须用类的对象调用。
静态方法也可以被对象共享访问,但是不推荐,因为静态方法直接用类名访问即可。
拓展:成员变量和成员方法访问的拓展。(面试常考)
方法:实例方法,静态方法。
成员变量:实例成员变量,静态成员变量。
8种访问形式的问答:
a.实例方法是否可以直接访问实例成员变量?可以的,因为它们都属于对象。
b.实例方法是否可以直接访问静态成员变量?可以的,静态成员变量可以被共享访问。
c.实例方法是否可以直接访问实例方法? 可以的,实例方法和实例方法都属于对象。
d.实例方法是否可以直接访问静态方法?可以的,静态方法可以被共享访问!
--------------------------------------------------------------------
a.静态方法是否可以直接访问实例变量? 不可以的,实例变量必须用对象访问!!
b.静态方法是否可以直接访问静态变量? 可以的,静态成员变量可以被共享访问。
c.静态方法是否可以直接访问实例方法? 不可以的,实例方法必须用对象访问!!
d.静态方法是否可以直接访问静态方法?可以的,静态方法可以被共享访问!!
成员变量和成员方法访问
拓展:成员变量和成员方法访问的拓展。(面试常考)
方法:实例方法,静态方法。
成员变量:实例成员变量,静态成员变量。
8种访问形式的问答:
a.实例方法是否可以直接访问实例成员变量?可以的,因为它们都属于对象。
b.实例方法是否可以直接访问静态成员变量?可以的,静态成员变量可以被共享访问。
c.实例方法是否可以直接访问实例方法? 可以的,实例方法和实例方法都属于对象。
d.实例方法是否可以直接访问静态方法?可以的,静态方法可以被共享访问!
--------------------------------------------------------------------
a.静态方法是否可以直接访问实例变量? 不可以的,实例变量必须用对象访问!!
b.静态方法是否可以直接访问静态变量? 可以的,静态成员变量可以被共享访问。
c.静态方法是否可以直接访问实例方法? 不可以的,实例方法必须用对象访问!!
d.静态方法是否可以直接访问静态方法?可以的,静态方法可以被共享访问!!
继承
概述
目标:继承(extends)的概述。
面向对象的三大特征:封装,继承,多态。
继承是Java中一般到特殊的关系,是一种子类到父类的关系。
例如:学生类继承了人类。 猫类继承了动物类。
被继承的类称为:父类/超类。
继承父类的类称为:子类。
继承的作用?
“可以提高代码的复用”,相同代码可以定义在父类中。
然后子类直接继承父类,就可以直接使用父类的这些代码了。
(相同代码重复利用)
子类更强大:子类不仅得到了父类的功能,它还有自己的功能。
继承的特点:
子类继承了一个父类,子类就可以直接得到父类的属性(成员变量)和行为(方法)了。
继承的格式:
子类 extends 父类{
}
小结:
继承是子类到到父类的一种关系。
子类继承了一个父类,子类就可以直接得到父类的属性和行为了。
在Java中继承是 “is a” 的关系。Cat extends Animal:猫是一个动物。
在Java中,子类是更强大的,子类不仅继承了父类的功能,自己还可以定义自己的功能。
继承的优势可以把相同的代码定义在父类中,子类可以直接继承使用。
这样就可以提高代码的复用性:相同代码只需要在父类中写一次就可以了。
子类不能继承父类的内容
目标:子类不能继承父类的内容。
引入:
子类继承父类,子类就得到了父类的属性和行为。
但是并非所有父类的属性和行为等子类都可以继承。
子类不能继承父类的东西:
子类不能继承父类的构造器:子类有自己的构造器。(没有争议的)
有争议的观点(拓展):
子类是否可以继承父类的私有成员(私有成员变量,私有成员方法)?
-- 我认为子类是可以继承父类的私有成员的,只是不能直接访问而已。
-- 以后可以暴力去访问继承自父类的私有成员~~~
子类是否可以继承父类的静态成员?
-- 我认为子类是不能继承父类的静态成员的,
-- 子类只是可以访问父类的静态成员,父类的静态成员只有一份可以被子类共享访问。
共享并非继承。
继承时成员变量的访问特定
目标:继承后成员变量的访问特点。
继承后成员变量的访问特点:就近原则
-- 子类有找子类,子类没有找父类,父类没有就报错!
如果一定要申明访问父类的成员变量可以使用:super.父类成员变量。
-- super指父类引用。
小结:
子类访问成员变量的原则:就近原则。
如果一定要访问父类的成员变量可以使用super关键字。
方法重写
目标:方法重写。
方法重写的概念:
子类继承了父类,子类就得到了父类的某个方法
但是子类觉得父类的这个方法不好用或者无法满足自己的需求
子类重写一个与父类申明一样的方法来覆盖父类的该方法,子类的这个方法
就进行了方法重写。
方法重写的校验注解: @Override
Java建议在重写的方法上面加上一个@Override注解。
方法一旦加了这个注解,那就必须是成功重写父类的方法,否则报错!
@Override优势:可读性好,安全,优雅!!
方法重写的具体要求:
1.子类重写方法的名称和形参列表必须与父类被重写方法一样。
2.子类重写方法的返回值类型申明要么与父类一样,要么比父类方法返回值类型范围更小。
3.子类重写方法的修饰符权限应该与父类被重写方法的修饰符权限相同或者更大。
4.子类重写方法申明抛出的异常应该与父类被重写方法申明抛出的异常一样或者范围更小!
方法重写的规范:
1.加上@Override注解。
2.建议“申明不变,重新实现”。
小结:
方法重写是子类重写一个与父类申明一样的方法覆盖父类的方法。
方法重写建议加上@Override注解。
方法重写的核心要求:方法名称形参列表必须与被重写方法一致!!
建议“申明不变,重新实现”。
super:代表了父类引用。
super可以用在子类的实例方法中调用父类被重写的方法。
目标:静态方法和私有方法是否可以被重写(拓展语法)
可以吗? 都不可以.
继承后构造器特点
目标:继承后构造器的特点。
继承后子类构造器的特点:
调用子类构造器的时候,子类的构造器一定会先调用父类的无参数构造器再执行自己的构造器。
为什么子类构造器一定要先调用父类无参数构造器:
1.子类的全部构造器的第一行默认有一个super()调用父类无参数构造器。
2.调用子类构造器初始化子类对象的时候,必须先调用父类构造器去初始化继承自父类的成员。
小结:
子类构造器默认一定会先调用父类的无参数构造器再执行自己。
目标:super调用父类构造器。
特点:
子类的全部构造器默认一定会调用父类的无参数构造器。
super(...):可以根据参数选择调用父类的某个构造器。
小结:
可以在子类构造器中通过super(...)根据参数选择调用父类的构造器,以便调用
父类构造器初始化继承自父类的数据。
this和super关键字使用总结
this关键字的作用:
this代表了当前对象的引用。
this关键字可以用在实例方法和构造器中。
this用在方法中,谁调用这个方法,this就代表谁。
this用在构造器,代表了构造器正在初始化的那个对象的引用。
总结与拓展:this和super关键字使用总结
this关键字代表了当前对象的引用。
this可以出现在方法,构造器中。
this出现在方法中:哪个对象调用这个方法this就代表谁。
this可以出现在构造器中:代表构造器正在初始化的那个对象。
this可以区分变量是访问的成员变量还是局部变量。
this代表了当前对象的引用(继承中指代子类对象):
this.子类成员变量。
this.子类成员方法。
this(...):可以根据参数匹配访问本类其他构造器。
super代表了父类对象的引用(继承中指代了父类对象空间)
super.父类成员变量。
super.父类的成员方法。
super(...):可以根据参数匹配访问父类的构造器。
拓展:this(...)根据参数匹配访问本类其他构造器。
注意:
this(...)借用本类其他构造器。
super(...)调用父类的构造器。
this(...)和super(...)必须放在构造器的第一行,否则报错!
所以this(...)和super(...)不能同时出现在构造器中!!!
Java是不是最好的语言?
只能找到合适的语言,而不能找到最好的语言。
Python
Go语言
C语言
Java WEB
微软的技术。
继承的特点
目标:继承的特点;
1.单继承:一个类只能继承一个直接父类。
为什么Java是单继承的?
答:反证法,假如Java可以多继承,请看如下代码:
class A{
public void test(){
System.out.println("A");
}
}
class B{
public void test(){
System.out.println("B");
}
}
class C extends A , B {
public static void main(String[] args){
C c = new C();
c.test(); // 出现了类的二义性!所以Java不能多继承!!
}
}
2.多层继承:一个类可以间接继承多个父类。(家谱)
3.一个类可以有多个子类。
4.一个类要么默认继承了Object类,要么间接继承了Object类,Object类是Java中的祖宗类!!
应用类型
目标:引用类型作为方法参数和返回值。
引用类型作为Java的数据类型,自然可以作为方法的参数类型和返回值类型。
除了基本数据类型都是引用数据类型了。
关注语法即可!!
小结:
引用类型作为数据类型可以在一切可以使用类型的地方使用!!
引用类型也可以定义成员变量,该成员变量有时候称为复合类型的变量
抽象类
概述
目标:抽象类的入门概述。
引入:
父类知道子类一定要完成某个功能,但是每个子类实现的情况都不一样
而且子类都会用自己的功能了,父类的该功能就可以定义成抽象的方法。
拥有抽象方法的类必须定义成抽象类。
什么是抽象方法?
没有方法体,只有方法签名,必须用abstract修饰的方法就是抽象方法。
什么是抽象类?
拥有抽象方法的类必须定义成抽象类。
抽象类必须用abstract关键字修饰。
小结:
抽象方法:没有方法体,只有方法签名,必须用abstract修饰的方法就是抽象方法。
抽象类:拥有抽象方法的类必须定义成抽象类,必须用abstract修饰。
// 抽象类:拥有了抽象方法的类必须定义成抽象类。抽象类必须加上abstract修饰。
abstract class Animal{
// 抽象方法:没有方法体,只有方法签名,必须加上abstract修饰。
public abstract void run();
}
作用
目标:抽象类的使用。
抽象类是为了被继承。
总结:
一个类继承了抽象类,必须重写完抽象类的全部抽象方法,否则这个类必须定义成抽象类。
因为拥有抽象方法的类必须定义成抽象类。
意义
目标:抽象类的意义。
抽象类存在的意义有两点:
(1)被继承,抽象类就是为了被子类继承,否则抽象类将毫无意义。(核心意义)
(2)抽象类体现的是"模板思想":部分实现,部分抽象。(拓展)
-- 可以使用抽象类设计一个模板模式。
特征
目标:抽象类的特征研究和深入。
抽象类的特征:有得有失。
有得:抽象类拥有了得到抽象方法的能力。
失去:抽象类失去了创建对象的能力。
面试题:抽象类是否有构造器,是否可以创建对象,为什么?
答:抽象类作为类一定有构造器,而且必须有构造器。
提供给子类继承后调用父类构造器使用的。
抽象类虽然有构造器,但是抽象类绝对不能创建对象。
抽象类中可能存在抽象方法,抽象方法不能执行。
抽象在学术上本身意味着不能实例化。
小结:
抽象类不能创建对象。
抽象类除了不能创建对象之外,类的其他成分它都具备!
抽象类中也可以没有抽象方法!!
设计模板模式
目标:使用抽象类设计一个模板模式。
设计模式:是前人(技术大牛,或者一些技术协会,或者一些大型知名的IT公司)
已经研发好或者设计好或者在实战开发中发现的的优秀软件设计思想,开源出去
后来者可以直接使用就能够得到很好的软件模式。
设计模式的目的:得到优秀的软件架构,从而提升代码的可重用性,扩展性,维护性,可读性。
模板模式是一种设计模式思想:
模板模式的作用:部分实现,部分抽象,可以极大的简化功能代码,提高开发效率
写一个模板模式的案例:作文模板。
作文模板:
标题和第一段 以及最后一段是固定的,
正文部分交给使用模板的人自己来实现。
小结:
抽象类是部分实现,部分抽象的含义,所以可以设计模板模式。
好处:模板可以确定的模板自己实现,模板不能确定的定义成抽象方法交给使用模板的人重写。
可以设计出优秀的设计模式,提升开发效率,提高代码的重用性!
class Teacher extends Template{
@Override
public String writeMain() {
return "\t\t我爸就是好,有多好,做他儿子才能懂~~~";
}
}
class Student extends Template{
@Override
public String writeMain() {
return "\t\t我爸爸很牛,我爸爸是马云,就是爽,很有钱~~~~";
}
}
// 1.写一个模板类:代表了作文模板。
abstract class Template{
private String title = "\t\t\t\t\t\t《我的爸爸》";
private String one = "\t\t我的爸爸很牛逼,到底有多牛呢,请看如下说明:";
private String last = "\t\t以上就是我的爸爸,简直太好了,下辈子还要做他儿子!";
// 2.提供一个写作文方法
public void write(){
System.out.println(title);
System.out.println(one);
// 正文:正文部分模板是不知道怎么写的!应该把正文部分定义成抽象方法
// 交给使用模板的子类重写!
System.out.println(writeMain());
System.out.println(last);
}
// 正文部分定义成抽象方法,交给子类重写!!
public abstract String writeMain();
}
注意事项和总结
目标:抽象类的注意事项和总结
1. 抽象类不能创建对象,如果创建,编译无法通过而报错。只能创建其非抽象子类的对象。
理解:假设创建了抽象类的对象,调用抽象的方法,而抽象方法没有具体的方法体,没有意义。
2. 抽象类一定有而且是必须有构造器,是供子类创建对象时,初始化父类成员使用的。
理解:子类的构造器中,有默认的super(),需要访问父类构造器。
3. 抽象类中,不一定包含抽象方法,但是有抽象方法的类必定是抽象类。
4. 抽象类的子类,必须重写抽象父类中所有的抽象方法,否则子类也必须定义成抽象类。
5. 抽象类存在的意义是为了被子类继承,抽象类体现的是模板思想。
理解:抽象类中已经实现的是模板中确定的成员,
抽象类不确定如何实现的定义成抽象方法,交给具体的子类去实现。
接口
概述
目标:接口的概述和定义等。(以理解和记住语法为主)
什么是接口?
接口是更加彻底的抽象,接口中全部是抽象方法和常量,没有其他成分。(JDK 1.8之前)
接口有啥用?
接口体现的是规范思想,实现接口的类必须重写完接口中全部的抽象方法。
规范 == 约束。
接口称为被实现,实现接口的类称为实现类。
定义接口的格式:
修饰符 interface 接口名称{
}
interface:定义接口的关键字。
接口中的成分研究(JDK 1.8之前):
1.抽象方法
a.接口中的抽象方法默认会加上public abstract修饰,所以可以省略不写。
2.常量
常量:是指有public static final修饰的成员变量,有且仅能被赋值一次,值不能改变。
常量的名称规范上要求全部大写,多个单词下划线连接。
常量修饰的public static final 可以省略不写,默认会加上。
小结:
定义接口使用的关键字:interface
接口中的成分在JDK 1.8之前只能有:常量和抽象方法。
在接口中常量的修饰符:public static final 可以省略不写,默认会加上。
在接口中抽象方法的修饰符:public abstract 可以省略不写,默认会加上。
基本实现
目标:接口的基本实现。
接口是用来被类实现的。
引入:
类与类是继承关系:一个类只能直接继承一个父类。
类与接口是实现关系:一个类可以实现多个接口。
实现接口的类称为“实现类”。
子类 继承 父类
实现类 实现 接口
实现类实现接口的格式:
修饰符 class 实现类名称 implements 接口1,接口2,接口3,....{
}
implements:实现的含义。
接口是可以被多实现的:一个类可以实现多个接口。
小结:
接口是用类被实现的,实现接口的类称为实现类。
实现接口的关键字是:implements。
接口是可以被类多实现的。
注意:一个类实现接口必须重写完接口中全部抽象方法,否则这个类必须定义成抽象类!!
目标:接口的多实现介绍。
实现类实现接口的格式:
修饰符 class 实现类名称 implements 接口1,接口2,接口3,....{
}
类与类是单继承。
类与接口是多实现。
小结:
一个类可以实现多个接口。
一个类如果实现了多个接口,必须重写完全部接口中的全部抽象方法
否则这个类必须定义抽象类。
目标:接口与接口的多继承。
引入:
类与类是单继承关系:一个类只能继承一个直接父类。
类与接口是多实现关系:一个类可以实现多个接口。
接口与接口是多继承关系:一个接口可以继承多个接口。
jdk8之后接口的新增方法
目标:JDK 1.8开始之后接口新增的三种方法(理解语法,属于Java自己的技术)
引入:
JDK 1.8之前接口中只能是抽象方法,常量。
JDK 1.8开始之后接口不再纯洁了。
JDK 1.8开始之后接口新增了如下三种方法。
a.默认方法(就是之前写的普通实例方法)
-- 必须用default修饰,默认会public修饰
-- 必须用接口的实现类的对象来调用。
b.静态方法
-- 默认会public修饰
-- 注意:接口的静态方法必须用接口的类名本身来调用。
c.私有方法(就是私有的实例方法): JDK 1.9才开始有的。
-- 只能在本类中被其他的默认方法或者私有方法访问。
实现多个接口的使用注意实现
拓展:实现多个接口的使用注意实现。(非常偏的语法,理解和了解即可)
1.如果实现了多个接口,多个接口中存在同名的静态方法并不会冲突,
原因是只能通过各自接口名访问静态方法。
2.当一个类,既继承一个父类,又实现若干个接口时,(重点)
父类中的成员方法与接口中的默认方法重名,子类就近选择执行父类的成员方法。
3.当一个类实现多个接口时,多个接口中存在同名的默认方法。
实现类必须重写这个方法。
4.接口中,没有构造器,不能创建对象。(重点)
接口是更彻底的抽象,连构造器都没有,自然不能创建对象!!
代码块
静态代码块
目标:代码块-静态代码块。
代码块是类的成分之一:
成员变量,方法,构造器,代码块,内部类。
代码块按照有无static修饰分为:
1.静态代码块。
2.实例代码块。
静态代码块的格式:
static {
}
静态代码块特点:
-- 必须有static修饰。
-- 会与类一起优先加载,且自动触发执行一次。
静态代码块作用:
-- 可以在执行类的方法等操作之前先在静态代码块中进行静态资源的初始化操作。
小结:
静态代码块有static修饰,与类一起加载,自动触发执行一次。
静态代码块的作用:可以用于在静态代码块中进行静态资源的初始化操作。
public class CodeDemo01 {
public static String schoolName ;
public static ArrayList<String> lists = new ArrayList<>();
// 静态代码块,属于类,与类一起加载一次!
static {
System.out.println("静态代码块被触发执行~~~~~~~");
// 在静态代码块中进行静态资源的初始化操作
schoolName = "黑马";
lists.add("3");
lists.add("4");
lists.add("5");
}
public static void main(String[] args) {
System.out.println(schoolName);
System.out.println(lists);
}
}
实例代码块
目标:代码块-实例代码块。
实例代码块的格式:
{
}
实例代码块的特点:
-- 无static修饰。
-- 会与类的对象一起加载,每次创建类的对象的时候,
实例代码块都会被加载且自动触发执行一次。
-- 实例代码块的代码在底层实际上是提取到每个构造器中去执行的!
实例代码块的作用:
-- 实例代码块可以在创建对象之前进行实例资源的初始化操作。
小结:
实例代码块无static修饰,属于对象,与对象一起加载执行。
实例代码块的代码在底层实际上是提取到每个构造器中去执行的!
实例代码块可以在创建对象之前进行实例资源的初始化操作。
public class CodeDemo02 {
private String name;
private ArrayList<String> lists = new ArrayList<>();
// 实例代码块!属于对象!与对象一起加载!
{
name = "小手";
lists.add("东");
lists.add("南");
lists.add("西");
lists.add("北");
System.out.println("实例代码块被触发执行一次~~~~~~~~");
}
public CodeDemo02(){
}
public CodeDemo02(String name){
}
public static void main(String[] args) {
CodeDemo02 c = new CodeDemo02();
System.out.println(c.name);
System.out.println(c.lists);
new CodeDemo02();
new CodeDemo02();
}
}
final关键字
目标:final关键字。
final是最终的含义。
final用于修饰:类,方法,变量。
1.final修饰类,类不能被继承了。
2.final可以修饰方法,方法就不能被重写了。
3.final修饰变量总规则:变量有且仅能被赋值一次。
拓展:final和abstract的关系?
互斥关系,不能同时修饰类或者同时修饰方法!!
目标:final修饰变量-局部变量。
final修饰变量的总规则:有且仅能被赋值一次。
变量有几种?
成员变量
-- 静态成员变量:有static修饰,属于类,只加载一份。
-- 实例成员变量:无static修饰,属于每个对象,与对象一起加载。
局部变量
-- 只能方法中,构造器中,代码块中,for循环中,用完作用范围就消失了。
final修饰局部变量:
-- 让值被固定或者说保护起来,执行的过程中防止被修改。
目标:final修饰静态成员变量。final修饰变量的总规则:有且仅能被赋值一次。final修饰静态成员变量,变量变成了常量。常量:有public static final修饰,名称字母全部大写,多个单词用下划线连接。拓展: final修饰静态成员变量可以在哪些地方赋值一次: 1.定义的时候赋值一次。 2.可以在静态代码块中赋值一次。 public class FinalDemo03 { // 常量:有public static final修饰,名称字母全部大写,多个单词用下划线连接。 public static final String SCHOOL_NAME = "黑马" ; public static final String SCHOOL_NAME1 ; static{ SCHOOL_NAME1 = "黑马1"; //SCHOOL_NAME1 = "黑马2"; // 报错,第二次赋值! }}
目标:final修饰实例成员变量。(了解。用不到)
final修饰变量的总规则:有且仅能被赋值一次。
拓展:
final修饰实例成员变量可以在哪些地方赋值1次:
1.定义的时候赋值一次。
2.可以在实例代码块中赋值一次。
3.可以在每个构造器中赋值一次。
单例模式
目标:面试必考(单例模式)。
单例模式的含义: 单例模式,是一种常用的软件设计模式。通过单例模式可以保证系统中,
应用该模式的这个类永远只有一个实例。即一个类永远只有一个对象实例。
单例的应用场景:在实际开发中,有很多业务对象永远只需要一个,无论启动多少次
我们只需要一个对象,例如任务管理对象,只需要一个对象。节约内存和性能。
因为对象越多内存占用越大,极有可能出现内存溢出!
实现单例模式两种方式:
1.饿汉单例设计模式
在用类获取对象的时候,对象已经提前创建好了。
设计步骤:
a.定义一个类,把构造器私有。
b.定义一个静态变量存储一个对象。
c.提供一个返回单例对象的方法。
2.懒汉单例设计模式
在真正需要该对象的时候,才去创建一个对象(延迟加载对象)。
设计步骤:
a.定义一个类,把构造器私有。
b.定义一个静态变量存储一个对象。
c.提供一个返回单例对象的方法。
// 饿汉单例设计模式
class Singleton01{
// b.定义一个静态变量存储一个对象( 在用类获取对象的时候,对象已经提前为你创建好了。)
private static final Singleton01 INSTANCE = new Singleton01();
// a.定义一个类,把构造器私有。
private Singleton01(){
}
// c.提供一个返回单例对象的方法。
public static Singleton01 getInstance(){
return INSTANCE;
}
}
public class SingleInstanceDemo01 {
public static void main(String[] args) {
Singleton01 s1 = Singleton01.getInstance();
Singleton01 s2 = Singleton01.getInstance();
System.out.println(s1 == s2);
}
}
// 懒汉单例设计模式
class Singleton02{
// b.定义一个静态变量存储一个对象(这里不能创建对象,需要的时候才创建,这里只是一个变量用于存储对象!)
public static Singleton02 instance ;
// a.定义一个类,把构造器私有。
private Singleton02(){
}
// c.提供一个返回单例对象的方法。
public static Singleton02 getInstance(){
if(instance == null){
// 第一次来拿单例对象!需要创建一次对象,以后直接返回!!
instance = new Singleton02();
}
return instance;
}
}
public class SingleInstanceDemo02 {
public static void main(String[] args) {
Singleton02 s1 = Singleton02.getInstance();
Singleton02 s2 = Singleton02.getInstance();
System.out.println(s1 == s2);
}
}
枚举
枚举概述
目标:枚举的概述和作用。
枚举是Java中的一种特殊类型。
枚举的作用:是为了做信息的标志和信息的分类。
定义枚举的格式:
修饰符 enum 枚举名称{
第一行都是罗列枚举实例的名称。
}
枚举类的编译以后源代码:
public final class Season extends java.lang.Enum<Season> {
public static final Season SPRING = new Season();
public static final Season SUMMER = new Season();
public static final Season AUTUMN = new Season();
public static final Season WINTER = new Season();
public static Season[] values();
public static Season valueOf(java.lang.String);
}
枚举的特点:
1.枚举类是用final修饰的,枚举类不能被继承!
2.枚举类默认继承了java.lang.Enum枚举类。
3.枚举类的第一行都是常量,存储都是枚举类的对象。
4.枚举类的第一行必须是罗列枚举类的实例名称。
所以:枚举类相当于是多例设计模式。
小结:
枚举类的特点:
1.枚举类是用final修饰的,枚举类不能被继承!
2.枚举类默认继承了java.lang.Enum枚举类。
3.枚举类的第一行都是常量,存储都是枚举类的对象。
4.枚举类的第一行必须是罗列枚举类的实例名称。
所以:枚举类相当于是多例设计模式。
// 枚举
enum Season {
SPRING , SUMMER , AUTUMN , WINTER;
}
枚举作用
目标:枚举的作用:是为了做信息的标志和信息的分类。
常量做信息分类和信息标志:
虽然可以实现可读性,但是入参不受限制!!!
Java建议做信息标志和信息分类应该使用枚举实现:最优雅的方式。
可以实现可读性,而且入参受限制,不能乱输入!!!
小结:
枚举的作用:是为了做信息的标志和信息的分类。
enum Oritation{
UP , DOWN , LEFT , RIGHT ;
}
public class EnumDemo02 {
public static void main(String[] args) {
move(Oritation.RIGHT); // 方法入参只能输入枚举的4个类型!
}
// 提供一个方法控制玛丽的方向。
// 上下左右
public static void move(Oritation o) {
switch (o) {
case UP:
System.out.println("让