JavaSE — 面向对象(下)

一、包装类及其用法

8种基本类型,不能当作对象使用:没有成员变量和方法

jdk1.5 提供了自动装箱和自动拆箱

基本数据类型包装类
byte(1字节,8位)Byte
short(2字节)Short
int(4字节)Integer
long(8字节)Long
char(2字节)Character
boolean(1字节)Boolean
float(4字节)Float
double(8字节)Double
  • java.lang.Integer源码中,系统把-128 ~ 127之间的整数自动装箱成Integer实例,并放入cache数组中缓存起来,所以当在对-128 ~ 127之间的整数进行装箱时,都是直接指向cache数组中的元素
  • 但是当把-128 ~ 127之外的整数进行装箱时,会重新创建一个Integer实例
二、处理对象
1、== 和 equals 方法
  • 对于基本类型,==判断值是否相等,对于引用类型,==判断地址是否相等
  • equals判断内容是否相等
2、常量池
  • 专门用来管理在编译时被确定并保存在已编译的.class文件中的一些数据,包括了关于类、方法、接口中的常量,还包括字符串常量
  • JVM常量池保证相同的字符串直接量只有一个
  • new出来的对象是在运行时才创建创建出来的,被保存在运行时内存区(堆内存),不会放入常量池
3、判断多个对象是否为同一个类的实例为什么不建议用 instanceof ?
// instanceof作用:判断 obj 是否为 Class 的实例对象
boolean result = obj instanceof Class
  • 当 obj 为 Class 的对象、直接或者间接子类、以及接口的实现类,都会返回true
  • 可以使用obj.getClass()
三、单例(Singleton)类

一个类始终只能创建一个实例,则为单例类

class Singleton(){
    // 使用一个类变量缓存,判断是否创建实例
    private static Singleton instance;
    // 构造方法私有
    private Singleton(){}
    
    public static Singleton getSingleton(){
        if(instance == null){
            // 创建一个 Singleton 对象,并进行缓存
            instance = new Singleton();
        }
        return instance;
    }
}

public class singletonTest(){
    public static void main(String[] args){
    	Singleton singleton1 = Singleton.getSingleton();
        Singleton singleton2 = Singleton.getSingleton();
        // 下行代码输出 true ,即为同一对象
        System.out.println(singletonq == singleton);
	}
}

四、final修饰符

final 变量获得初始值后,不能被重新赋值

1、final成员变量
  • 成员变量是随类的初始化或者对象初始化而初始化的

  • 成员变量的初始值,可以在以下3个地方指定初始值

    1)、定于该变量时

    2)、初始化块(类变量为静态初始化块)

    3)、构造器中(只有实例变量)

  • 所以,在定义 final 变量时,显式的初始化

2、final局部变量
  • 系统不会对局部变量进行初始化,所以需要显式初始化
  • final修饰的局部变量,在定义事可以不赋值,但是后面只能赋值一次
3、final修饰基本类型变量和引用类型变量的区别
  • 修饰基本变量时,不能对变量重新赋值
  • 修饰引用变量时,不能改变引用变量的所引用的地址,但是可以改变引用对象的值
4、可执行“宏替换”的final变量

对于一个 final 变量来说,不管是类变量、实例变量还是局部变量,只要满足3个条件,该变量就不是一个变量,而是一个直接量

  • 使用final修饰
  • 定义变量时指定初始值
  • 该初始值可以在编译时就被确定下来

例如可以是:

// 以下 a、b、c都是直接量
final int a = 3 + 3;
final String b = "chang" + "ge";
final String c = "a" + 3;
// d 不是直接量,调用了方法,无法在编译时确定下来
final String d = "a" + String.valueOf(66);
// e 是直接量,虽然看起来调用了变量,无法在编译时确定下来
// 但是 b、c都是 final 修饰,在编译时确定,是直接量
final String e = b + c;
5、final修饰方法、类
  • final修饰的方法不可被重写
  • final修饰的类不能被继承
五、抽象类
1、抽象类和抽象方法
  • 抽象方法:普通方法加上abstract修饰符,并且只有方法,没有方法体
  • 抽象类:普通类加上abstract修饰符即可
  • 抽象类可以有成员变量方法(普通方法和抽象方法都可以)构造器初始化块
  • 抽象类不能被实例化,只能被子类实现
2、abstract注意点
  • abstract 不能修饰成员变量、不能修饰局部变量、也不能修饰构造器
  • static 修饰的方法,表明该方法属于类本身,通过类名可以直接调用,但是被 abstract 修饰时,没有方法体,会调用出错,也就是说不能同时用 static 和 abstract 修饰同一个方法
  • static 和 abstract 可以同时修饰内部类
  • 同时,抽象方法要被子类继承实现才有方法体,才有意义,也就是抽象方法不能被 private 修饰了
六、接口

接口继承使用extend关键字

  • 接口是一种特殊的抽象类,抽象得更彻底
  • 接口里可以包含静态常量抽象方法、类方法、默认和私有方法内部类定义
1、使用接口
  • 接口不能用于创建实例,但是可以用于声明引用类型变量(多态)
  • 实现接口方法时,必须使用比接口访问权限更大的的修饰符,一般是public
2、接口和抽象类区别
  • 接口只有抽象方法、静态方法、默认方法和私有方法;抽象类还可以有普通方法
  • 接口只有静态常量;抽象类还可以有普通成员变量
  • 接口无构造器;抽象类有构造器,是为了给子类调用完成抽象类的初始化,不能实例
  • 接口无初始化块;抽象类有初始化块
3、面向接口编程

简单工厂模式(又叫静态工厂方法模式):是专门定义一个类来负责创建其他类的实例,被创建的实例通常都有共同的父类(或者父接口)

七、内部类

定义在其他类内部的的类就被成为内部类

  • 内部类可以访问外部类的私有数据(因为内部类被外部类当作类成员,而同一个类成员之间可以相互访问),但是外部类不能访问内部类是实现细节,例如成员变量等
  • 内部类比外部类多三个修饰符:privateprotectedstatic
  • 但是注意:非静态内部类不能拥有静态成员

注意:外部类的上一级程序单元是包,所以它只有两个作用域:同一个包和任意位置,也就是说刚好对应访问权限修饰符中的publicdefault

1、非静态内部类
  • 内部类大多数都是作为成员内部类定义,而不是作为局部内部类
  • 局部内部类和匿名内部类则不是类成员
2、静态内部类

static 修饰的内部类

因为 static 关键字是把类成员变成类相关,而不是实例相关,而外部类上一级是包,也就不存在再变成类成员,内部类上一级是外部类就可以用 static 修饰

  • 为什么静态内部类的实例方法不能访问外部类的实例属性?

    因为静态内部类是外部类相关的,而不是外部类的实例相关

    也就是说静态内部类实例时寄生在外部类的类本身的,只有外部类的引用

3、局部内部类

每个内部类都能独立的继承一个接口的实现,所以无论外部类是否已经继承了某个(接口的)实现,对于内部类都没有影响。内部类使得多继承的解决方案变得完整

  • 对于局部内部类而言,不管是局部变量还是局部内部类,它们的上一级程序单元都是方法,而不是类

  • 当需要局部内部类定义变量、创建实例和派生子类时,都只能在局部内部类所在的方法内进行

4、匿名内部类

只能使用一次,无法在其他地方调用

  • 匿名内部类不能是抽象类,因为系统在创建匿名内部类使,会立即创建匿名内部类的对象
  • 匿名内部类不能定义构造器,因为没有类名,但是可以通过初始化块,来完成构造器所需要做的事
八、Java 8 新增的Lambda表达式

Lambda 表达式支持将代码作为方法参数

一般用来创建只有一个抽象方法的接口实例(也就是函数式接口)

可以理解为按-> 分左右,左边是参数列表,右边是抽象方法的实现逻辑

//匿名内部类写法
new Thread(new Runnable() {
	@Override
	public void run() {
		System.out.println("内部类写法");
	}
}).start();
//lambda 写法
new Thread(() -> System.out.println("lambda写法")).start();
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值