个人简介
> 个人主页:是Lay的主页
> 学习方向:JAVA后端开发
> 种一棵树最好的时间是十年前,其次是现在!
> ⏰往期文章:【Java基础】面向对象基础
> 喜欢的话麻烦点点关注喔,你们的支持是我的最大动力。
活动地址:CSDN21天学习挑战赛
目录
1. static静态关键字
2. static应用知识: 工具类
3. static应用知识: 代码块
4. static应用知识: 单例
5. 面向对象三大特征之二: 继承
1. static是什么?
1). static是静态的意思,可以用来修饰成员变量, 成员方法
2). static修饰成员变量之后称为静态成员变量(类变量), 修饰方法之后称为静态方法(类方法)
3). static修饰后的成员变量, 可以被类的所有对象共享(访问, 修改)
2. static修饰的成员变量是什么?有什么特点?
1). 静态成员变量(有static修饰, 属于类、加载一次, 内存中只有一份), 访问格式
类名.静态成员变量(推荐)
对象.静态成员变量(不推荐)
2). 实例成员变量(无static修饰, 属于对象), 访问格式
对象.实例成员变量
3. 两种成员变量各自在什么情况下定义?
1). 静态成员变量: 便是在线人数等需要被类的所有对象共享的信息时
2). 实例成员变量: 属于每个对象, 且每个对象的该信息不同时(如: name, age, money...)
4. 成员方法的分类和访问分别时什么样的?
1). 静态成员方法(有static修饰,属于类和对象共享) 访问格式
类名.静态成员方法
对象.静态成员方法(不推荐)
2). 实例成员方法(无static修饰, 属于对象) 访问格式
对象.实例成员方法
5. 每种成员方法的使用场景时怎么样的?
1). 表示对象自己的行为的, 且方法中需要直接访问实例成员,则该方法必须申明成实例方法
2). 如果该方法是以执行一个通用功能为目的,或者需要方便访问,则可以申明成静态方法
6. static访问注意事项:
1). 静态方法只能访问静态的成员, 不可以直接访问实例成员
2). 实例方法可以访问静态的成员, 也可以访问实例成员
3). 静态方法中是不可以出现this和super关键字的
1. 工具类是什么?
类中都是一些静态方法,每个方法都是以完成一个共用的功能为目的,这个类用来给统开发人员共同使用的。
2. 工具类是什么,有什么好处?
内部都是一些静态方法,每个方法完成一个功能
一次编写,处处可用,提高代码的重用性。
3. 工具类有什么要求?
建议工具类的构造器私有化处理。
工具类不需要创建对象。
1. 代码块概述
代码块是类的5大成分之一(成员变量、构造器,方法,代码块,内部类),定义在类中方法外。 在Java类下,使用 { } 括起来的代码被称为代码块 。
2. 静态代码块 static { }
位置:类里方法外
执行时机:随着类的加载而加载,最先加载到内存,优先于对象进行加载,直到类小消失,它才会消失
作用:一般用来加载那些只需要加载一次并且第一时间就需要加载资源,称作:初始化
3. 构造代码块 { }
位置:类里方法外
执行时机:创建对象时执行,创建几次,执行几次,并且优先于构造方法执行
作用:用于提取所有构造方法的共性功能
4. 局部代码块 { }
位置:方法里
执行时机:当其所处的方法被调用时才会执行
作用:用于限制变量的作用范围,出了局部代码块就失效
5. 代码块之间的顺序:
静态代码块 -> 构造代码块 -> 构造方法 -> 普通方法【如果普通方法里有局部代码块,局部代码块才会执行】
1. 什么是设计模式(Design pattern)
开发中经常遇到一些问题,一个问题通常有n种解法的,但其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,称之为设计模式。
设计模式有20多种,对应20多种软件开发中会遇到的问题。
学设计模式主要是学2点:
第一:这种模式用来解决什么问题。
第二:遇到这种问题了,该模式是怎么写的,他是如何解决这个问题的。
2. 单例模式
可以保证系统中,应用该模式的这个类永远只有一个实例,即一个类永远只能创建一个对象。
例如任务管理器对象我们只需要一个就可以解决问题了,这样可以节省内存空间。
3. 单例的实现方式
饿汉单例模式。
懒汉单例模式。
4. 饿汉式的实现思路:
1)把本类的构造方法私有化–为了不让外界调用构造函数来创建对象
2)通过本类的构造方法创建对象,并把这个对象也私有化,为了防止外界调用
3)提供公共的全局访问点向外界返回本类的唯一的一个对象
注意:公共方法需要设置成静态–需要跳过对象,通过类名直接调用这个返回本类对象的公共方法
对象也需要设置成静态的–这个对象需要在静态方法中被返回,而静态只能调用静态
懒汉式的实现思路:
==延迟加载的思想:==我们有的时候有些资源并不是需要第一时间就创建出来,所以需要延迟到需要时再创建
这样既可以提升性能,又可以节省资源
1)把本类的构造方法私有化–为了不让外界调用构造函数来创建对象
2)创建了一个本类类型的引用类型变量【这个变量后续用来保存创建出来的对象的地址值】
3)提供公共的全局访问点向外界返回本类的唯一的一个对象
注意:这个公共的方法里,需要做判断
如果引用类型的变量值为null,说明:之前没有创建过本类对象–创建后再赋值给引用类型变量,并把它返回
如果引用类型的变量值不为null,说明:
之前有创建过本类对象,这个引用类型变量保存就是地址值,本次不再新建对象,直接返回
这个只是一个开始,远远没有结束,大家还可以继续拓展:装饰者 建造者 工厂
1. 前提 :继承可以实现程序的复用性,减少代码的冗余
2. 我们通过extends关键字建立子类与父类的继承关系:格式:子类 extends 父类
3. 继承相当于子类把父类的功能复制了一份,包括私有资源
注意:虽然私有资源继承了,但是私有资源不可用,原因是被private限制了访问,私有资源只能在本类使用
注意:构造方法不能继承,原因是:构造方法要求名字是本类的类名,我们不能在子类中出现父类名字的构造方法
4. 继承是可以传递的:爷爷的功能会传给爸爸,爸爸的功能会传给孙子
注意:爸爸从爷爷那里继承的功能,也会一起传给孙子
5. Java的类是单继承的:一个子类只能有一个父类,但是一个父类可以有多个子类
6. 子类在继承了父类以后,如果对父类的功能不满意
可以在不修改父类功能的【满足OCP原则】前提下,在子类中,重写继承过来的这个方法
重写需要满足的规则:两同 两小 一大,我们可以在重写的方法上加@Override注解验证是否写对
7. 继承是一种is a的关系,强耦合,关联性特别强,而且类的继承机会只有一次,要谨慎使用
8. 子类可以直接使用父类的所有非私有资源
练习题:
package com.example.bbb;
import java.util.Random;
import java.util.Scanner;
/*本类用于复习面向对象的相关知识*/
public class TestOOP {
public static void main(String[] args) {
//8.提示并接收用户传入的宠物昵称
System.out.println("请您输入宠物的名字:");
String name = new Scanner(System.in).nextLine();
//9.触发对应的构造函数,创建小猫类的对象
Cat c = new Cat(name);
//10.与宠物做互动
System.out.println("按回车执行:");
while(true){
new Scanner(System.in).nextLine();
int r = new Random().nextInt(6);
switch (r){
case 0:c.feed();break;
case 1:c.play();break;
default:c.punish();break;
}
}
}
}
//1.创建父类:宠物类,描述宠物这一类事物
class Pet{
//2.定义宠物类的属性
String name;//电子宠物的姓名
int full;//饱食度
int happy;//快乐度
//3.1 生成本类的全参构造
public Pet(String name, int full, int happy) {
this.name = name;
this.full = full;
this.happy = happy;
}
//3.2 创建本类的含参构造
public Pet(String name){
//只需要用户起宠物名即可,饱食度与快乐度的初始值都是50
//实际上底层会触发全参构造,名字是用户起的,其他两个是预先设置好的默认值
this(name,50,50);
}
//4.1定义宠物类的功能1--喂宠物吃东西
public void feed(){
//先判断宠物是不是吃饱了,如果吃饱了,结束整个喂食方法
if(full == 100){
System.out.println(name+"已经吃饱啦~");
return;//遇到return关键字,整个方法直接结束
}
//如果没有吃饱,就给宠物喂食,一次增加10的饱食度
System.out.println("给"+name+"喂食:");
full = full + 10;
System.out.println("饱食度:"+full);
}
//4.2定义宠物类的功能2--陪宠物玩
public void play(){
//先判断宠物还有没有饱食度,如果没有饱食度了,就不能玩了,结束整个玩的方法
if(full == 0){
System.out.println(name+"已经饿的玩不动了...");
return;//遇到return关键字,整个方法直接结束
}
//如果饱食度不为0,就可以玩耍,每次玩耍快乐度+10,饱食度-10
System.out.println("陪"+name+"玩耍");
happy += 10;
full -= 10;
System.out.println("快乐度:"+happy);
System.out.println("饱食度:"+full);
}
//4.3定义宠物类的功能3--宠物的惩罚方法
public void punish(){
System.out.println("打"+name+"的PP,哭叫声:"+cry());
happy -= 10;
System.out.println("快乐度:"+happy);
}
//4.4定义一个哭的方法--宠物被打哭了
public String cry(){
return "此处有哭叫声";//这个位置没有明确的叫声,因为子类会重写
}
}
//5.创建子类小猫类
class Cat extends Pet{
//6.由于父类的无参构造已经没有了,所以这里要手动调用父类的含参构造
public Cat(String name) {//养猫的时候要给猫起昵称
super(name);//表示调用父类的含参构造
}
//7.重写父类的cry();
@Override
public String cry(){
return "喵~";
}
}
1. 方法重写是什么样的?
子类写一个与父类申明一样的方法覆盖父类的方法。
2. 方法重写建议加上哪个注解,有什么好处?
@Override注解可以校验重写是否正确,同时可读性好。
3. 重写方法有哪些基本要求?
1). 重写方法的名称和形参列表应该与被重写方法一致。
2). 私有方法不能被重写。
3). 子类重写父类方法时,访问权限必须大于或者等于父类被重写的方法的权限。
4. this的用法:
1.当成员变量与局部变量同名时,使用this指定成员变量
2.使用this在构造方法的第一行调用构造方法的功能
this();–调用的是本类的无参构造
this(参数);–调用的是本类对应参数的构造方法
5. super的用法:
1.当父类的成员变量与子类的变量同名时,使用super指定父类的成员变量
2.使用super在子类构造方法的第一行调用父类构造方法的功能
super();–调用的是父类的无参构造
super(参数);–调用的是父类对应参数的构造方法
6. 继承中的构造方法
1). 子类在创建对象时,默认会先调用父类的构造方法
2). 原因是子类构造函数中的第1行默认存在super();–表示调用父类的无参构造
3). 当父类没有无参构造时,可以通过super(参数);调用父类的其他含参构造
注意:子类必须调用父类的一个构造函数,不论是无参还是含参,选一个即可
4). 构造方法不可以被继承!因为语法的原因,要求构造方法的名字必须是本类类名
不能在子类中出现一个父类名字的构造方法