JavaSE(面向对象 常用类 集合框架)

面向对象

对象和类之间的关系

对象:

对象是人们要进行研究任何事物,一切事物都可以认为是对象。
对象具有状态和行为:
对象具有状态,比如姓名,年龄,性别等。
对象还有操作,比如吃饭,睡觉,写代码等。

类:
具有相同特性(状态)和行为(功能)的对象的抽象就是类。因此,对象的抽象是类,类的具体化就是对象,也可以说类的实例是对象,类实际上就是一种数据类型
类具有特性,对象的状态,用成员变量来描述,封装数据。
类具有功能,对象的行为,用方法来描述。

理解:对象是类的实例,类是对象的模板。

对象的操作和创建

  1. 根据类来创建对象的语法:
    类名 变量 = new 类名();
  2. 给字段设置值:
    对象变量.字段名 = 该类型的值;
  3. 获取字段的值:
    该字段类型 变量 = 对象变量.字段值;
  4. 通过对象调用方法.
    对象变量.方法(实参);

构造器

构造器的作用:

  • 创建对象,必须和 new 一起使用
  • 完成对象的初始化操作

构造器的特点:

  • 构造器的名称和当前所在类的名称相同
  • 禁止定义返回类型,千万不要使用void作为返回类型.
  • 在构造器中,不需要使用return语句

static关键字

static修饰的资源属于类级别,而不是对象级别。

static修饰符的特点:

  • static修饰的成员(字段/方法),随着所在类的加载而加载.
  • 优先于对象的存在.
  • satic修饰的成员被该类型的所有对象所共享.
  • 直接使用类名访问static成员

那么,static的方法可以调用static修饰的方法,不能调用没有用static修饰的方法

​ 没有static修饰的方法可以调用static修饰的方法

什么时候定义成static的字段和方法?

​ 如果这个一个状态/行为属于整个事物(类),就直接使用static修饰.被所有对象所共享.

各种类型变量的比较

存在位置生命周期开始生命周期结束在内存中的位置
类变量类中字段,使用static修饰字节码文件被加载进JVMJVM停止方法区
实例变量类中字段,没有使用static修饰创建所在类的对象时该对象被GC回收
局部变量方法形参,代码块中,方法内代码执行到初始化变量时所在方法/代码块结束当前方法的栈帧

局部变量定义后,必须显示初始化后才能使用,因为系统不会为局部变量执行初始化操作。这就意味着,定义局部变量后,系统并未为这个变量分配内存空间。
直到程序为这个变量赋值时,系统才会为局部变量分配内存,并将初始值保存到该内存中。
局部变量不属于任何类或实例,因此它总是保存在其所在方法的栈内存中。
基本数据局部变量:直接把这个变量的值保存到该变量所对应的内存中。
引用数据局部变量:这个变量内存中存的是地址,通过该地址引用到该变量实际引用堆里的的对象。
栈内存中的变量无需系统垃圾回收,其往往随方法或代码块的运行结束而结束。

开发中应尽量缩小变量的作用范围

代码块

在类或者在方法中,直接使用"{}"括起来的一段代码,表示一块代码区域。

代码块里变量属于局部变量,只在自己所在区域(前后的{})内有效。
根据代码块定义的位置的不同,我们又分成三种形式:

局部代码块:直接定义在方法内部的代码块:
一般的,我们是不会直接使用局部代码块的,只不过我们会结合if,while,for,try等关键字联合,表示一块代码区域.

初始化代码块(构造代码块): 直接定义在类中

​ 每次创建对象的时候都会执行初始化代码块,每次创建对象都会调用构造器,在调用构造器之前,会先执行本类中的初始化代码块

在这里插入图片描述
**静态代码块:**使用static修饰的初始化代码块

​ 在主方法执行之前执行静态代码块,且只执行一次 main是程序主入口,为什么静态代码块会优先于main执行?

​ 静态成员随着字节码的加载也加载进JVM,此时main方法还没执行,因为方法需要JVM调用.
​ 先把字节码加载进JVM, 而后JVM再调用main方法.

在这里插入图片描述

封装

  • 把对象的状态和行为看成一个统一的整体,将二者存放在一个独立的模块中(类);
  • “信息隐藏”, 把不需要让外界知道的信息隐藏起来,尽可能隐藏对象功能实现细节,向外暴露方法,保证外界安全访问功能; 把所有的字段使用private私有化,不准外界访问,把方法使用public修饰,允许外界访问.
    把所有数据信息隐藏起来,尽可能隐藏多的功能,只向外暴露便捷的方法,以供调用.

封装的好处:

  • 使调用者正确,方便地使用系统功能,防止调用者随意修改系统属性.
  • 提高组件的重用性.
  • 达到组件之间的低耦合性(当某一个模块实现发生变化时,只要对外暴露的接口不变,就不会影响到其他模块).

访问修饰符

修饰符类内部同一包下子类任何地方
private
protected
public

this关键字

this表示当前对象

this主要存在于两个位置

  • 构造器中:表示当前创造的对象
  • 方法中:哪一个对象调用this所在的方法,this就指代的是哪个对象

使用this可以

  1. 解决成员变量和局部变量的二义性(防止混淆同名变量)
  2. 一个类中实例方法的互相调用(可以省略this)
  3. 构造器重载的互相调用,this([参数]) 必须写在构造方法第一行
  4. static不能和this一起使用 (当字节码文件被加载进JVM,static成员就产生了,此时还没有创建对象)

继承

基于某个父类对对象的定义加以拓展,而产生新的子类定义,子类可以继承父类原来的某些定义,也可以增加原来父类所没有的定义,或者覆写父类中的某些特性。

父类存放共性,子类存放特性,子类继承父类的共性,解决了代码的重复问题

继承关系的真正作用:表示出一个体系

子类可以继承父类哪些东西

  1. 如果父类中的成员使用**public修饰,子类可以继承**.
  2. 如果父类中的成员使用**protected修饰,子类也可继承**,即使父类和子类不在同一个包中.
  3. 如果父类和子类在**同一个包中,此时子类可以继承父类中缺省修饰符的成员**.
  4. 如果父类中的成员使用private修饰,子类打死都继承不到.因为private只能在本类中访问.
  5. 父类的构造器,子类也不能继承,因为构造器必须和当前的类名相同

super关键字

使用场景:

  • 在子类方法中,调用父类被覆盖的方法,此时必须使用super.
  • 在子类构造器中,调用父类构造器,此时必须使用super语句且必须写在第一行 (默认是有的,不用自己再写)

子类初始化过程:

​ 在创建子类对象之前,会先创建父类对象.调用子类构造器之前,在子类构造器中会先调用父类的构造器,默认调用的是父类无参数构造器

1): 如果父类不存在可以被子类访问的构造器,则不能存在子类.
2):如果父类没有提供无参数构造器,此时子类必须显示通过super语句去调用父类带参数的构造器.

static不能和this super共存

实例解析

子类继承不到父类的private字段, 但是可以继承父类的getset方法 通过这些getset方法加上调用(super)父类的带参的构造器

通过构造器我们可以给子类赋值 ,这样也就间接的继承到了父类的私有字段 new相当于创建父类对象 引用的还是父类属性

而**子类无需再定义这些字段**

在这里插入图片描述

方法重写 (override)与重载(overload)

重写:一同两小一大

  • 在父子类继承当中
  • 实例**方法签名**相同(方法签名=方法名+参数列表)
  • 子类方法的**返回值类型**是和父类方法的返回类型相同或者是其子类(小)
  • 子类方法声明抛出的**异常类型**和父类方法声明抛出的异常类型相同或者是其子类(小)
  • 子类方法的**访问权限比父类方法访问权 限更**或相等

重载: 一同两不同

  • 一个类中**方法名**相同
  • 参数**类型个数**不同

final

可以修饰类 属性和方法 表示最终的

被final修饰的类是一个最终类

  • 不能被继承

被final修饰的变量是一个常量

  • 必须初始化才能使用
  • 不能重新赋值

被final修饰的方法

  • 不能被重写

什么时候可以把一个类设计成final类?

只要满足一下任意一个条件即可:

​ 1.某类不是专门为了继承而设计

​ 2.出于安全考虑,类的实现细节不许再修改,不准修改源代码

​ 3.确信该类不会再被拓展

**final修饰基本类型变量:**表示该变量的值不能改变,即不能用“=”号重新赋值

**final修饰引用类型变量:**表示该变量的引用的地址不能变,而不是引用地址里的内容不能变。

组合关系

继承关系: 子类可以继承到父类中部分的成员,那么此时子类是可以修改到父类的信息的.
继承关系破坏封装,为了复用代码可能会让子类具有不该具有的功能.

在这里插入图片描述

如果A类为了得到B类的功能行为:

​ A类如果是B类的一种特殊情况,使用继承,否则使用组合关系

多态

同一事物下的 不同表现形态

前提:

  • 必须要有**继承或实现**关系

  • 必须要有方法的重写

  • 子类的实例赋值给父类类型的变量

//Animal是Cat父类 new一个子类对象 赋值给Animal类型的cat变量
Animal cat=new Cat();
// 编译类型: 声明对象变量的类型,Animal,表示把对象看出什么类型.
// 运行类型: 对象的真实类型,Cat 运行类型就是对象的真实类型
```

当编译类型和运行类型不同的时候,多态就出现了

多态的**特点**: 把子类对象赋给父类变量,在运行时期会表现出具体的子类特征(调用子类的方法).

多态的**作用:当把不同的子类对象都当作父类类型来看待,可以屏蔽不同子类对象之间的实现差异**,从而写出通用的代码达到==通用编程==,以适应需求的不断变化。

引用类型转换

基本类型转换

自动类型转换: 把小类型的数据 赋给 大类型的变量. (此时的大和小表示的容量范围)
byte b = 12; byte是1个字节
int i = b; int是4个字节

强制类型转换: 把大类型的数据赋给 小类型的变量.
short s = (short) i ;short是2个字节

引用类型的转换
引用类型的大和小,指的是 父类 和子类的关系.
自动类型转换: 把子类对象赋给父类变量(多态).
Animal a = new Dog();
Object是所有类的根类:
Object obj = new Dog();
强制类型转换: 把父类类型对象赋给子类类型变量(当时该父类类型变量的真实类型应该是子类类型).
Animal a = new Dog();
Dog d = (Dog)a;

instanceof 运算符: 判断该对象是否是某一个类的实例.
语法格式:boolean b = 对象A instanceof 类B; // 判断 A对象是否是 B类的实例,如果是,返回true.

多态与类中变量和方法的关系

多态时,是调用不到子类独有的方法和字段的

测试方法

class testClass{
    public static void main(String[] args) {
        SuperClass subClass = new SubClass();
        subClass.doWork();
    }
}
//下图分情况讨论结果

在这里插入图片描述

字段不存在多态特性
在这里插入图片描述

通过对象调用字段,在**编译时期**就已经决定了要调用哪一块内存空间的数据

字段不存在重写的概念,在多态时,不能有多态的特征即在运行时期不能体现子类的特征(属性);

实例解析

在这里插入图片描述

工具类的封装

**设计模式:**是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性

工具类如何设计: 工具在开发中其实只需要存在一份即可.
1):如果工具方法没有使用static修饰,说明工具方法得使用工具类的对象来调用.
此时把工具类设计为单例的.
2):如果工具方法全部使用static修饰,说明工具方法只需要使用工具类名调用即可.
此时必须把工具类的构造器私有化(防止创建工具类对象调用静态方法).

建议使用第二种

单例模式(饿汉式)

在这里插入图片描述

abstract关键字

使用abstract修饰且没有方法体的方法,称为抽象方法。

抽象方法的特点:

  • 使用抽象abstract修饰,方法没有方法体,留给子类去实现/覆盖
  • 抽象方法修饰符**不能是**private 和 final以及static
  • 抽象方法必须定义在抽象类或接口中

使用abstract修饰类,该类就是抽象类

抽象类的特点:

  • 不能创建实例即不能new一个抽象类,即使创建出抽象类对象,调用抽象方法,根本没有方法体。(调用父类方法,可以继承父类)
  • **抽象类是有构造器的,**子类构造器必须先调用父类构造器,可以不包含抽象方法,若一旦包含,该类必须作为抽象类,抽象类可以包含普通方法,构造器可以传递参数用。
  • 若子类没有实现/覆盖父类所有的抽象方法,那么子类也得作为抽象类(抽象派生类)。
  • 构造方法不能都定义成私有的,否则不能有子类
  • **抽象类不能使用final修饰,**因为必须要有子类 子类再去实现抽象方法,被final修饰就不能有子类
  • 抽象类是不完整的类,需作为父类(必须要有子类),功能才能得以实现

接口

定义接口语法: [public] interface 接口名{}

成功编译之后,和类一样,具有一份字节码

接口只定义了类应当遵循的规范,却不关心这些类的内部数据和其功能的实现细节。

理解:接口是更严格的抽象类

因为抽象类里有抽象方法和非抽象方法,接口只能有抽象方法

接口的特点:

  • 没有构造方法,也不能显示定义构造器,不能实例化。
  • 接口只能继承接口,不能继承类,且接口支持多继承(类是单继承关系)。
  • 接口里的方法方法全是抽象的,默认修饰符是public abstract。
  • 接口里的字段全是全局静态常量,默认修饰符是public static final。
  • 接口里的内部类全是公共静态的,默认修饰符是public static。

接口中的成员

  1. 接口中没有构造器,推论:接口不能创建对象(不能 new ),接口中不能定义普通方法.

  2. 接口中定义的成员变量,实质是全局静态常量,默认使用 public static final来修饰.

      public static final String NAME = "张三";
    
  3. 接口中定义的方法都是公共的抽象方法,默认的使用 public abstract 来修饰方法.

       public abstract void walk();
    

    一般的,我们在接口中定义方法,不喜欢使用修饰符.

  4. 接口中定义的内部类都是公共的静态内部类,默认使用public static来修饰内部类.

    public static interface ABC{}   
    

接口中的多态

其实,接口只是特殊的类,弥补了java只能单继承的缺陷

在这里插入图片描述

常用类

Object

Object类中常见的方法

  • protected void finalize() :当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
    垃圾回收器在回收某一个对象之前,会先调用该方法,做扫尾操作. 该方法我们不要去调用.

  • Class getClass() :返回当前对象的真实类型。即拿到.class文件

  • int hashCode(): 返回该对象的哈希码值,hashCode决定了对象再哈希表中的存储位置,不同对象的hashCode是不一样的.

  • boolean equals(Object obj): 拿当前对象(this)和参数obj做比较,在Object类中的equals方法,本身和 “ == ”符号相同,都是比较对象的内存地址,建议每个类都应该重写equals方法,不要比较内存地址,而去比较我们关心的数据,因为我们关心的是内容数据,而不是内存地址 基本类型对比的是内容,引用类型比较的是内存地址

  • **String toString():**表示把一个对象转换为字符串.打印对象时,其实打印的就是对象的toString方法

    打印的是对象的十六进制的hashCode值,但是我们更关心对象中存储的数据. 建议重写toString方法

包装类

在面向对象中,”一切皆对象” 那么

//age代码哪里有对象???   这只是基本类型变量,不是对象
int age=17;

基本数据类型缺少对象,如果要有对象,那么必须得有类

八大基本数据类型的包装类都使用final修饰,都是最终类,都不能被继承.

基本数据类型包装类
byteByte
shortShort
intInteger
longLong
charCharacter
floatFloat
doubleDouble
booleanBoolean

**装箱:**把基本类型数据转成对应的包装类对象。
**拆箱:**把包装类对象转成对应的基本数据类型数据。

Java8是自动进行装箱和拆箱的 底层依然是装箱和拆箱操作,只是简化开发

//装箱
//方式1
Integer num1=new Integer(17);
//方式2
Integer num2=Integer.valueOf(17);
//拆箱
int num3=num1.intValue(); 
//自动装箱  直接将基本类型赋值给包装类对象
Integer num4=17;
//自动拆箱:  直接将包装类对象赋给对应的基本类型
int num5=num4;

基本类型和包装类型之间的转化

  • 装箱:
  Integer i1 = new Integer(123);
  Integer i2 = Integer.valueOf(123);//推荐,带有缓存.    
  • 拆箱:

     int val = i1.intValue();
    

String类型和基本类型/包装类型之间的转化

  • 把String转换为包装类类型:

    //方式1 
    Integer i1 = Integer.valueOf(123);
    //方式2
     Integer i2= new Integer(123);
    
  • 把包装类对象转换为String.

    String  str =  任何对象.toString();
    
  • 把基本数据类型转换为String

    String str=123+"";
    
  • 把String转换为基本数据类型:

    // static xxx parseXxx(String s)      :xxx表示8大基本数据类型
    String  input=12345;
    int num = Integer.parseInt(input);
    

包装类和基本数据类型之间的区别 (以int和Integer举例)

  • 默认值

    ​ int的默认值是0.
    ​ Integer的默认值为null.

  • 包装类中提供了该类型相关的很多算法操作方法

    ​ static String toBinaryString(int i) :把十进制转换为二进制
    ​ static String toOctalString(int i) : :把十进制转换为八进制
    ​ static String toHexString(int i) : :把十进制转换为十六进制

  • 在集合框架中,只能存储对象类型,不能存储基本数据类型值

    Integer和int不是相同的数据类型

在这里插入图片描述

String

String对象的创建:
1):直接赋一个字面量: String str1 = “ABCD”;
2):通过构造器创建: String str2 = new String(“ABCD”);

两种方式有什么区别,分别在内存中如何分布?

字符串的比较操作:

  • 使用”==”号: 只能比较引用的内存地址是否相同.
  • 使用equals方法: String类重写了Object的equals方法,比较的是字符内容.

常量池:专门存储常量的地方,都指的方法区中

String str1 = “ABCD”; 最多创建一个String对象,最少不创建String对象.
如果常量池中,以及存在”ABCD”,那么str1直接引用,此时不创建String对象.
否则,先在常量池先创建”ABCD”内存空间,再引用.

String str2 = new String(“ABCD”);
最多创建两个String对象,至少创建一个String对象.
new关键字:绝对会在堆空间,创建内存区域. 常量池存在ABCD则指向它所以至少创建一个String个对象.

在这里插入图片描述

String对象比较:
在这里插入图片描述

  • 单独使用" "**引号创建**的字符串都是直接量,编译期就已经确定存储到常量池中
  • 使用**new String("")创建**的对象会存储到堆内存中,是运行期才创建;
  • 使用只包含直接量的字符串连接符如**“aa” + "bb"创建**的也是直接量编译期就能确定,已经确定存储到常量池中;
  • 使用包含String直接量(无final修饰符)的字符串表达式(如"aa" + s1)创建的对象是运行期才创建的,存储在堆中;

StringBuffer和StringBuilder

String和StringBuilder以及StringBuffer的区别(建议使用StringBuilder):
StringBuffer和StringBuilder都表示可变的字符串,功能方法都是相同的.

唯一的区别:
StringBuffer: StringBuffer中的方法都使用了synchronized修饰符,表示同步的,在多线程并发的时候可以保证线程安全,保证线程安全 的时候,性能(速度)较低.
StringBuilder:StringBuilder中的方法都没有使用了synchronized修饰符,不安全,但是性能较高.

StringBuffer的构造方法:

  • public StringBuffer():无参构造方法
  • public StringBuffer(String str):指定字符串内容的字符串缓冲区对象

StringBuffer的方法:

  • public int length():返回长度(字符数)

StringBuffer的添加功能:

  • public StringBuffer append(String str):可以把任意类型数据添加到字符串缓冲区里面,并返回字符串缓冲区本身

更多方法详情可以点击在线文档

文档

在线文档地址 https://docs.oracle.com/javase/8/docs/api/index.html

  • 文档的创建和转换

    ​ byte[] getBytes():把字符串转换为byte数组
    ​ char[] toCharArray():把字符串转换为char数组
    ​ String(byte[] bytes):把byte数组转换为字符串
    ​ String(char[] value):把char数组转换为字符串

  • 获取字符串信息

    ​ int length() 返回此字符串的长度
    ​ char charAt(int index) 返回指定索引处的 char 值
    ​ int indexOf(String str)返回指定子字符串在此字符串中第一次出现处的索引。
    ​ int lastIndexOf(String str)返回指定子字符串在此字符串中最右边出现处的索引

  • 字符串比较判断

    ​ boolean equals(Object anObject) 将此字符串与指定的对象比较。
    ​ boolean equalsIgnoreCase(String anotherString) 将此 String 与另一个 String 比较,不考虑大小写
    ​ boolean contentEquals(CharSequence cs) 将此字符串与指定的 CharSequence 比较

  • 字符串大小写转换

    ​ String toUpperCase() 把当前字符串转换为大写(谁调用该方法,谁就是当前字符)
    ​ String toLowerCase() 把当前字符串转换为小写

集合框架

集合框架是为表示和操作集合而规定的一种统一的标准的体系结构。

三大块内容:对外的接口、接口的实现和对集合运算的算法(底层都对应着某一种数据结构的算法)。

为什么需要集合框架? 专注于业务开发,而不是数据结构和算法.

常用的集合类:

  • Set(集):集合中的对象不按特定方式排序,不允许元素重复.

  • List(列表):集合中的对象按照索引位置排序,允许元素重复.

  • Map(映射):集合中每一个元素都包含一对key和value对象.不允许key对象重复,值对象可以重复.

    集合类的操作方法:

  • 增加:
    boolean add(Object e) 将指定元素添加到此向量的末尾,等价于addElement方法。
    void add(int index, Object element) 在此向量的指定位置插入指定的元素。
    boolean addAll(Collection c) :把c集合中的元素添加到当前集合对象中.

  • 删除:
    Object remove(int index) :删除指定索引位置的元素,并返回删除之后的元素.
    boolean remove(Object o):删除指定的元素.
    boolean removeAll(Collection c):从此集合中移除包含在指定 集合c中的所有元素。
    boolean retainAll(Collection c):在此集合中仅保留包含在指定 集合c中的元素,求两个集合的交集

  • 查询:

    ​ int size() :返回当前集合中存储几个元素.
    ​ boolean isEmpty():判断当前集合中元素个数是否为0.
    ​ Object get(int index):查询指定索引位置的元素.
    ​ Object[] toArray():把集合对象转换为Object数组.

  • 修改:

    ​ Object set(int index, Object element) :修改当前集合中指定索引位置的元素.返回被替换的旧的元素.

    更多方法详情可以点击在线文档

集合迭代操作

把集合做的元素一个一个的遍历取出来.

迭代器对象:
Iterator: 迭代器对象,只能从上往下迭代.
boolean hasNext(); 判断当前指针后是否有下一个元素
Object next():获取指针的下一个元素,并且移动指针.

  • 查询:

    ​ int size() :返回当前集合中存储几个元素.
    ​ boolean isEmpty():判断当前集合中元素个数是否为0.
    ​ Object get(int index):查询指定索引位置的元素.
    ​ Object[] toArray():把集合对象转换为Object数组.

  • 修改:

    ​ Object set(int index, Object element) :修改当前集合中指定索引位置的元素.返回被替换的旧的元素.

    更多方法详情可以点击在线文档

集合迭代操作

把集合做的元素一个一个的遍历取出来.

迭代器对象:
Iterator: 迭代器对象,只能从上往下迭代.
boolean hasNext(); 判断当前指针后是否有下一个元素
Object next():获取指针的下一个元素,并且移动指针.

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值