2022-7-27 第八组-曹雨-面向对象
代码块
类的内部结构:
属性、方法、、构造器、代码块、内部类
代码块:
- 代码块又称为初始化块,属于类的一个成员,它是将逻辑语句封装在方法体中。
- 通过{}包裹。代码块没有方法名,没有参数,没有返回值,只有方法体,
- 它是不需要通过对象或类进行显式的调用,它会在类加载或者创建对象时
- 主动的《隐式》调用。
(1)静态代码块:
static {
// 静态代码块
System.out.println("静态代码块...");
}
(2)实例代码块:
{
// 实例代码块
System.out.println("实例代码块...");
}
一个类中,静态代码块旨在开始调用,而实例代码块一旦每次调用都会
比如如上代码
public class Ch01 {
final String STR;
static {
// 静态代码块
System.out.println("静态代码块...");
}
{
// 实例代码块
System.out.println("实例代码块...");
}
public static void main(String[] args) {
Ch01 ch01 = new Ch01();
Ch01 ch02 = new Ch01();
}
}
运行结果为:

可以看到,静态代码块,只在一开始被调用,而实例代码块每次new一个对象都会被调用
今日面试题:
public class Father {
public Father() {
System.out.println("父类的构造器...");
}
{
System.out.println("父类的实例块...");
}
static {
System.out.println("父类的静态块...");
}
public static void main(String[] args) {
Father father = new Father();
}
在一个类中,当同时有构造器,实例块,静态块时。谁先被调用,谁后被调用。
程序运行结果为:

可以看到静态块依然最先被调用,实例块紧随其后,构造器最后被调用。
此时加入一个Ch02继承于Father,它同样有自己的构造器,静态块,实例块。创建子类对象后,是什么顺序。
public class Ch02 extends Father {
public Ch02() {
System.out.println("子类的构造器...");
}
{
System.out.println("子类的实例块...");
}
static {
System.out.println("子类的静态块...");
}
public static void main(String[] args) {
new Ch02();
}
}
结果是:

一般规律是:
父亲>孩子
静态块>实力块>构造器
结论:
- 当没有继承关系,就一个类,静态块---实力块---构造器
- 当有继承关系,父类静态块---子类静态块---父类实力块---父类构造器---子类实力块---子类构造器
静态 static(也可以叫类属性,类方法)
可以修饰属性,方法,代码块
修饰属性(方法和代码块同理)
public class Ch03 {
static String name = "里奥·梅西";
}
按照传统方式:
Ch03 ch03 = new Ch03();
ch03.name;
如果这个属性前面有“static”我就可以直接用“类名.name”
Ch03.name;来调用
用“static”修饰的属性不属于任何一个对象,直接属于一个类。我可以直接通过类名去调
static内存解析:
- 1、静态的变量或者静态方法存在于方法区的。静态的结构不会被垃圾回收。
- 2、不属于某一个实例对象,只存在于方法区。调用静态结构,直接用类名.的方式。
Java的垃圾回收机制:
int a = 20;
这个a使用完成后,JVM会自动回收
而如果你是静态变量
static a = 20;
不会回收。
static修饰的变量都储存在“方法区”中。
实例方法与静态方法的互相调用
创建一个实例方法
public void fun(){
}
在静态方法中对其进行调用
public static void show(){
fun();
}
是不可以的,会报错:

正确的方式是
public static void show(){
Ch03().fun();
}
1、静态方法中可以直接调用实例方法吗?
- 不可以!!!如果想用,必须对象.方法名
2、实例方法中可以直接调用静态方法吗?
- 可以!!!
静态的结构的加载,随着类的加载而加载!!!
非静态的结构,随着对象的创建而加载!!
出现顺序
静态 先于 非静态
实例方法不能单独调用,必须通过对象调
静态方法不管在哪都是“类名.方法名”
静态方法没有重写这个概念的!
this和super
-
无论是this还是super,都不可以在静态结构中使用。
-
this和super。this.方法。super.方法
-
静态结构是属于类的,静态结构是优先于对象就存在的。
-
this和super,必须有对象才能出现。必须得有实例。
外部类
-
一个public声明的类,类名必须和.java的文件名相同。
-
生成的.class文件是两个独立的.class
-
外部类就是两个类。正常使用
-
开发中,尽量不要写外部类。
public class Ch05 { int i = 10; public static void main(String[] args) { } } class Outer { public static void main(String[] args) { } }
设计模式:
程序设计师之间沟通的“行话”
面向对象的设计原则:
1、开闭原则(Open Close Principle)
- 对扩展开放,对修改关闭。(继承,实现接口)
- 我们可以通过“抽象约束,封装变化”来实现开闭原则。
- 通过接口或者抽象类为软件定义一个相对稳定的抽象层。
- 将相同的可变因素封装在相同的具体实现类中。派生一个实体类就可以了。
2、里氏代换原则
- 子类继承父类时,除了添加新的方法完成新增的功能外,尽量不要重写父类的方法
3、依赖倒转原则
- 要面向接口编程,不要面向实现编程。
a、每个类尽量提供接口或抽象类,或者两者兼备
b、变量的类型声明尽量是接口或者是抽象类
c、任何类都不应该从具体类派生
d、使用继承时,要遵循里氏代换原则。
4、接口隔离原则
- 使用多个隔离的接口。
5、迪米特法则
6、合成复用原则
7、单一原则:一个类只做一件事
单例模式(一个类只有一个实例):
基本思路:
- 别人不能new,构造器私有化,不能在类的外部通过new去实例化
- 在该类内部产生一个唯一的实例对象,把它封装成static类型
- 定义一个静态方法返回这个唯一的对象。
饿汉式:
以基本思路为方法,在类中直接创建一个单例对象
//饿汉式单例模式。
//不管以后会不会使用到该实例化对象,先创建了再说,很着急的样子。
//实现的办法就是直接new实例化。
public class Ch03{
private static final Ch03 ch03 = new Ch03();
private Ch03(){}
public static Ch03 getInstance(){return ch03;}
}
懒汉式:
你要用到我,并且类里没有实例对象,我就被你调用。
什么时候调用getInstance方法,什么时候new
public Ch04 {
//将自身实例化对象设置称为一个属性,此时并没有赋值
private static Ch04 ch04;
//将构造器私有化
private Ch04(){}
public static Ch04 getInstance() {
}
}
浙公网安备 33010602011771号