oop高级1

类与对象(高级)

1.类变量

类名.类变量名

  1. static变量是同一个类的所有对象共享

  2. static类变量,在类加载的时候就生成了

语法: 房屋修饰符 static 数据类型 变量名;

说明:1.类变量是随着类的加载而创建,所以即使没有创建对象实例也可以访问

2.类变量的访问,必须遵守相关的访问权限

类方法

联想类变量

注意事项:

  1. 类方法中无this的参数,普通方法中隐含着this的参数

  2. 类方法可以通过类名调用,也可以通过对象名调用 (类名.类方法名)

  3. 普通方法不能通过类名调用(可以 new D().say();)

  4. 类方法中不允许使用和对象有关的关键字,比如this和super

  5. 类方法只能访问静态成员

  6. 普通成员方法可以访问静态成员,也可以访问非静态成员

调用本类中的方法不会默认调用该类中的构造器,当new对象时会自动调用构造器初始化值

小结:

静态方法,只能访问静态的成员;非静态的方法,可以访问静态成员和非静态成员

2.main方法语法

深入理解main方法:

public static void main(String[] args) {}
  1. main方法是Java虚拟机调用

  2. java虚拟机需要调用类的main方法,所以该方法的访问权限必须是public

  3. java虚拟机在执行main方法时不必创建对象,所以该方法必须是static

  4. 该方法接收String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数,格式如下

  5. java 执行的程序 参数1 参数2 参数3

注意:在main方法中,我们可以直接调用main方法所在类的静态成员

但是,不能直接访问该类中的非静态成员,必须创建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员

通过idea传参数

Edit Configurations

3. 代码块

基本语法:

[修饰符]{
 代码  
};

分为静态代码块和非静态代码块

应用场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的复用性

不管调用哪个构造器创建对象,都会调用代码块的内容

代码块调用的顺序优先于构造器

注意事项:

  1. static静态代码块,对类进行初始化,它随着类的加载而执行(类只会加载一次),并且只会执行一次;普通代码块,每创建一个对象,就执行,和类是否加载无关,普通代码块是构造器的补充

  2. 类什么时候被加载? 1创建对象实例时;2创建子类对象实例,父类也会被加载;3使用类的静态成员时

  3. 如果只是使用类的静态成员时,普通代码块并不会执行

  4. 创建一个对象时,在一个类调用顺序是:

(1).调用静态代码块和静态属性初始化(调用优先级一样,如果有多个,则按照定义的顺序调用)

(2).调用普通代码块和普通属性的初始化(如上)

(3).调用构造器

  1. 构造器的最前面其实隐含了super();和调用普通代码块

  2. 存在继承关系时,调用顺序?(首先是类加载)

(1).父类的静态代码块和静态属性

(2).子类的静态代码块和静态属性

(3).父类的普通代码块和普通属性初始化

(4).父类的构造方法

(5).子类的普通代码块和普通属性初始化

(6).子类的构造方法

  1. 静态代码块只能调用静态成员,普通代码块可以调用任意成员

4. 单例模式

在类中只有一个对象(单例)

(1).饿汉式

对象在类加载时就已经创建好

  1. 将构造器私有化

  2. 在类的内部直接创建对象 (该对象是static)

  3. 提供一个公共的static方法,返回 gf对象

(2).懒汉式

只有当用户使用了getInstance方法时,才返回cat对象;而当再次调用时,会返回上次创建的cat对象,从而保证了单例

  1. 将构造器私有化

  2. 定义一个static静态属性对象 (初始为null)

  3. 提供一个public的static方法,可以返回一个cat对象

小结;

  1. 创建对象的时机不同

  2. 懒汉式存在线程安全问题

  3. 饿汉式存在浪费资源的问题

5. final关键字

被final修饰的类不能被继承;(用于修饰符后)方法不能被重写;局部变量不能被修改

细节:

  1. 当修饰变量时(非静态);1.直接赋值;2.在构造器中赋值; 3.在代码块中赋值

  2. 当修饰变量时(静态):1.直接赋值;2.在静态代码块中赋值;不能在构造器中赋值

  3. final类虽然不能被继承,但是可以实例化对象

  4. 如果一个类已经是final类,就没有必要再将方法修饰成final方法

  5. final不能修饰构造器

  6. final和static往往搭配使用,效率更高,不会导致类加载

final可用于形参类型前

6. 抽象类

当一个类中存在抽象方法时,需要将该类声明为abstract类;一般来说,抽象类会被继承,由其子类来实现抽象方法

abstract用于修饰符后,抽象方法没有方法体

细节:

  1. 抽象类不能被实例化

  2. 抽象类不一定包含抽象方法,但含有抽象方法的类一定是抽象类

  3. abstract只能修饰类或方法

  4. 抽象类可以有任意成员

  5. 如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也是抽象类

  6. 抽象方法不能使用private,final,static来修饰,因为这些关键字都是和重写相违背的

模板设计模式

abstractExercise2

7. 接口

接口给出一些没有实现的方法,封装到一起,到某个类要使用时,再根据具体情况把这些方法写出来

语法:

interface 接口名{
   //属性
   //方法
}
===================
class 类名 implements 接口{
   自己属性
   自己方法
   必须实现的接口的抽象方法
}

在接口中,抽象方法可以省略abstract

jdk8以后,可以有默认实现方法(default),和静态方法

注意:

  1. 接口不能被实例化

  2. 接口中所有方法是 public 方法;接口中抽象方法可以不用abstract 修饰

  3. 一个普通类实现接口,就必须将该接口的所有方法都实现 (重写) 。alt + enter

  4. 抽象类去实现接口时,可以不实现接口的抽象方法

  5. 一个类同时可以实现多个接口

  6. 接口中的属性是 public static final 来修饰的

  7. 接口中的属性访问形式:接口名.属性名

  8. 接口不能继承其他的类,但是可以继承多个别的接口

  9. 接口的修饰符 只能是 public 和默认,这点和类的修饰符是一样的

实现接口 VS 继承类

1.接口和继承解决的问题不同

继承的价值主要在于:解决代码的复用性和可维护性

接口的价值主要在于:设计,设计好各种规范(方法),让其他类去实现这些方法

2.接口比继承更加灵活

继承是满足 is - a 的关系,而接口只需满足 like - a 的关系

接口在一定程度上实现代码解耦 (即:接口规范性 + 动态绑定 )

接口的多态特性(类似继承)

  1. 多态参数:接口引用可以指向实现了该接口的类的对象

If ifo1 = new Monster;
  1. 多态数组

  2. 接口的多态传递:”如果 IG extends IH 接口,而 Teacher 类也实现了 IG 接口,那么,实际上就相当于 Teacher 类也实现了 IH接口“

8. 内部类

一个类的内部又完整的嵌套了另一个结构。被嵌套的类称为内部类,嵌套其他类的类称为外部类。

类的五大成员:属性、方法、构造器、代码块、内部类

内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系

语法:

class Outer{   //外部类
   class Inter{    //内部类    
  }
}
class Other{   //外部其他类
}

内部类的分类

定义在外部类局部位置上(比如方法内):

  1. 局部内部类(有类名)

  2. 匿名内部类(无类名,!!!!!!!)

定义在外部类的成员位置上:

  1. 成员内部类(没用static修饰)

  2. 静态内部类(用static修饰)

1. 局部内部类的使用:

  1. 局部内部类定义在方法 / 代码块中

  2. 作用域(能用)在方法体或代码块中

  3. 访问方式 创建对象再访问(注意:必须在作用域内

  4. 本质仍然是一个类

  5. 外部其他类 不能访问 局部内部类 (局部内部类地位是一个局部变量)

  6. 如果外部类的成员和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,可以使用(外部类名 .this .成员

2. 匿名内部类的使用:

本质是内部类;该类没有名字;同时还是一个对象

  1. 基本语法

new 类或接口(参数列表){
   类体;
};

例:

IA tiger = new IA{
}

JDK底层在创建匿名内部类 Outer04$1 ,立即就创建了 Outer04$1 实例,并且把地址返回给了tiger

  1. 匿名内部类使用一次就不能再使用 (不能再new)

  2. 可以直接访问外部类的所有成员

  3. 作用域:仅仅在它所在的方法或代码块中

  4. 外部其他类不能访问匿名内部类(匿名内部类地位是一个局部变量)

  5. 如果外部类和匿名内部类的成员重名时,内部类访问的话,默认遵循就近原则;如果想访问外部类的成员,可以使用(外部类名. this . 方法名)

应用场景:

当成对象传入方法(接口,方法重写)(该方法通过传入的匿名内部类调用重写的接口方法(传对象时使用匿名内部类)

3. 成员内部类的使用:

成员内部类定义在外部类的成员位置上,没有static修饰

  1. 可以直接访问外部类的所有成员

  2. 可以添加任意访问修饰符,因为它的地位就是外部类的一个成员

  3. 作用域:和外部类其他成员一样,为整个类体

  4. 外部类访问成员内部类(如何调用内部类方法? 外部类对象-->方法-->成员内部类对象-->方法)

  5. 外部类名.this.方法名

  6. 外部其他类访问成员内部类?

(1)外部类名.new 成员内部类名创建成员内部类对象

(2)在外部类中编写方法,可以返回成员内部类对象 return new Inter();

 

 

 

 

 

posted @ 2022-01-10 21:59  两生jh  阅读(52)  评论(1)    收藏  举报