面对对象高阶

目录

一.static(静态的)

1.1 static使用范围

 1.2静态属性语法格式与静态方法格式

1.3 静态变量与静态方法的特点

静态变量

静态变量的默认值

 静态方法

1.4变量的分类

 1.4代码解析

静态属性

静态方法 

二.单例(Singleton)设计模式

1.饿汉式

2.懒汉式

对比

3.特点、优缺点

三.代码块

3.1代码块(或初始化块)的作用: 

3.2代码块(或初始化块)的分类

3.3使用:

​编辑​编辑

代码解析

 ​

四..属性(实例变量)赋值

 4.1.给类的非静态的属性(实例变量)赋值的位置有:

4.2. 执行的先后顺序

4.3.代码解析

五.final关键字的使用

 5.1 final可以用来修饰的结构

 5.2final修饰

5.3final与finally与finalize

六.抽象类与抽象方法 

6.1 abstract的概念

6.2 abstract可以修饰

6.3语法格式

6.3abstract修饰类

6.4 abstract修饰方法

6.5abstract 不能修饰哪些结构

 6.6 abstract 不能与哪些关键字共用

 七.接口(interface)的使用

7.1接口的理解

7.2接口内部结构的说明即格式

7.3接口与类的关系即实现

7.4格式

7.5接口作用

 7.6接口与接口的关系

7.7 接口的多态性

7.8抽象类和接口

 7.9补充

7.10总结

八.内部类

8.1内部类定义即格式

8.2分类

8.3成员内部类的理解+实例化静态内部类和实例化非静态

8.4匿名(重要)

4种匿名方式 

个人理解  

代码解析 

提供了接口的实现类的对象分析

提供了接口的实现类的匿名对象分析

 提供了接口的匿名实现类的对象分析

 提供了接口的匿名实现类的匿名对象分析

代码分析 

 提供接口匿名实现类的对象分析

提供接口匿名实现类的匿名对象分析

 提供了继承于抽象类的匿名子类的对象分析

九.枚举类 

9.1使用

 9.2jdk5.0之前,使用自定义枚举类的方法。步骤如下:

9.3在jdk5.0时,加入使用 enum定义枚举类。步骤如下:

9.4Enum类中常用的方法

9.5枚举类实现接口

 十.包装类

10.1为什么要使用包装类?

10.2基本数据类型对应的包装类类型

10.3自定义包装类

10.4装箱

10.5拆箱

10.6基本数据类型、包装类与字符串间的转换 

10.61基本数据类型转为字符串

 10.62 字符串转为基本数据类型

方式 1:使用 parseXxx 静态方法将字符串参数转换为对应的基本类型(除了 Character 类)

方式 2:字符串转为包装类,然后可以自动拆箱为基本数据类型

方式 3:通过包装类的构造器实现 

10.7总结 

十一.进制转换

11.1十进制转二进制

11.2十进制转八进制 

11.3十进制转十六进制

11.4任意进制转换

Integer.toString(int i, int radix)方法将十进制数decimal转换为指定进制radix的字符串表示 

十二.大小写转化

12.1小写字母转大写字母

 12.2大写字母转小写字母



一.static(静态的)

1.1 static使用范围

在 Java 类中,可用 static 修饰属性、方法、代码块、内部类

被修饰后的成员具备以下特点:

        随着类的加载而加载

        优先于对象存在

        修饰的成员,被所有对象所共享

        访问权限允许时,可不创建对象,直接被类调用

 1.2静态属性语法格式与静态方法格式

使用 static 修饰的成员变量就是静态变量(或类变量、类属性)

[修饰符] class 类{

[其他修饰符] static 数据类型 变量名;

}

用 static 修饰的成员方法就是静态方法。

[修饰符] class 类{

[其他修饰符] static 返回值类型 方法名(形参列表){

                方法体

        }

1.3 静态变量与静态方法的特点

静态变量

         静态变量的默认值规则和实例变量一样。

        静态变量值是所有对象共享。

        静态变量在本类中,可以在任意方法、代码块、构造器中直接使用。

        如果权限修饰符允许,在其他类中可以通过“类名.静态变量”直接访问,也可以通过 “对象.静态变量”的方式访问(但推荐使用类名.静态变量的方式)。

        静态变量的 get/set 方法也静态的,当局部变量与静态变量重名时,使用“类名.静态变量”进行区分。 

静态变量的默认值

  1. 基本数据类型

    • byte:默认值为0。
    • short:默认值为0。
    • int:默认值为0。
    • long:默认值为0L。
    • float:默认值为0.0f。
    • double:默认值为0.0d。
    • boolean:默认值为false。
    • char:默认值为'\u0000'(空字符)。
  2. 引用类型

    • 默认值为null,表示没有引用任何对象。
  3. 数组

    • 数组的每个元素都会根据其类型自动初始化为默认值。

静态变量:

类中的属性使用static进行修饰。 对比静态变量与实例变量:

① 个数

        静态变量:在内存空间中只有一份,被类的多个对象所共享。

        实例变量:类的每一个实例(或对象)都保存着一份实例变量。(有几个对象有多少实列变量)

② 内存位置

        静态变量:jdk6及之前:存放在方法区。 jdk7及之后:存放在堆空间

        实例变量:存放在堆空间的对象实体中。

③ 加载时机

        静态变量:随着类的加载而加载,由于类只会加载一次,所以静态变量也只有一份。

        实例变量:随着对象的创建而加载。每个对象拥有一份实例变量。

④ 调用者

        静态变量:可以被类直接调用,也可以使用对象调用。

        实例变量:只能使用对象进行调用

⑤ 判断是否可以调用

        从生命周期的角度解释

                        类变量   实例变量

        类             yes         no

        对象         yes         yes

⑥ 消亡时机

         静态变量:随着类的卸载而消亡

         实例变量:随着对象的消亡而消亡

 静态方法

        静态方法在本类的任意方法、代码块、构造器中都可以直接被调用。

        只要权限修饰符允许,静态方法在其他类中可以通过“类名.静态方法“的方式调用。也可以通过”对象.静态方法“的方式调用(但推荐使用类名.静态方法的方式)。

        在 static 方法内部只能访问类的 static 修饰的属性或方法,不能访问类的非 static 的结 构。

        静态方法可以被子类继承,但不能被子类重写。

        因为不需要实例就可以访问 static 方法,因此 static 方法内部不能有 this,也不能有 super。如果有重名问题,使用类名.”进行区别。 

        随着类的加载而加载

        可以通过“类.静态方法”的方式,直接调用静态方法

        静态方法内可以调用静态的属性或静态的方法。不可以调用非静态的结构。(如:属性、方法)

        判断是否可以调用        

                        类方法         实例方法

                类         yes                 no

                对象       yes                yes

         static修饰的方法内,不能使用this和super 

        补充:在类的非静态方法中,可以调用当前类中的静态结构(属性、方法)或非静态结构(属性、方法)

1.4变量的分类

方式1:按照数据类型:基本数据类型、引用数据类型

方式2:按照类中声明的位置:

成员变量:按照是否使用static修饰进行分类:

        使用static修饰的成员变量:静态变量、类变量

        不使用static修饰的成员变量:非静态变量、实例变量

    局部变量概念:方法内、方法形参、构造器内、构造器形参、代码块内的变量等

 1.4代码解析

public class Accoraed {
    public static void main(String[] args) {


        Bank accoraed = new Bank();
        System.out.println(accoraed);
        
        Bank accoraed1 = new Bank();
        accoraed1.setPassword("000000");
        
        System.out.println(accoraed1);
        Bank accoraed2 = new Bank();
        accoraed2.setBalance(5000);
        System.out.println(accoraed2.getBalance());
       
         Bank.setInterestRate(0.045);
        Bank.setMinBalance(10);
       
         System.out.println("银行存款的利率为:" + Bank.getInterestRate());
        System.out.println("银行存款的最低余额为:" + Bank.getMinBalance());

    }
}







/**
 * packageName exer14.test1
 *
 * @author 曦
 * @version 1.0
 * @className Bank
 * @date 2024/10/29 18:25
 * @description TODO 编写一个类实现银行账户的概念,包含的属性有“帐号”、“密码”、“存款余额”、“利率”、“最小余额”,定义封装这些属性的方法。
 * 账号要自动生成。
 * 编写主类,使用银行账户类,输入、输出3个储户的上述信息。
 */
public class Bank {
    private int id;//账号
    private String password;//密码
    private double balance;//存款余额
    private static double interestRate = 0.043;//利率
    private static double minBalance = 1.0;//最小余额
    private static int init = 1001;//自动生成账号

    /**
     *@description TODO:
     *@description : Bank
     * @param :
      * @param  * return null
     *@author 曦
     *@throws
     *@return {@link null}
     *@date 2024/10/29 18:56
    **/

    public Bank() {
        this.id = init++;// 使用静态变量init生成唯一账号
        password = "123456";// 设置默认密码为"123456"
    }

    /**
     *@description TODO:
     *@description : Bank
     * @param balance:
    	 * @param id:
    	 * @param password:

     *@author 曦
     *@throws
     *@return {@link  @return: null}
     *@date 2024/10/29 19:44
    **/

    public Bank(double balance, int id, String password) {
        this.balance = balance;// 设置账户余额
        this.id = init++;// 使用静态变量init生成唯一账号
        this.password = password;// 设置账户密码
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public static double getInterestRate() {
        return interestRate;
    }

    public static void setInterestRate(double interestRate) {
        Bank.interestRate = interestRate;
    }

    public static double getMinBalance() {
        return minBalance;
    }

    public static void setMinBalance(double minBalance) {
        Bank.minBalance = minBalance;
    }

    /**
     *@description TODO:重写toString方法
     *@description : toString
     * @param :
     *@author 曦
     *@throws
     *@return {@link  @return: java.lang.String}
     *@date 2024/10/29 19:48
    **/
    @Override
    public String toString() {
        return "Bank{" +
                "id=" + id +
                ", password='" + password + '\'' +
                ", balance=" + balance +
                '}';
    }
}

静态属性

private static double interestRate = 0.043;//利率
    private static double minBalance = 1.0;//最小余额
    private static int init = 1001;//自动生成账号

静态方法 

 public static double getInterestRate() {
        return interestRate;
    }

    public static void setInterestRate(double interestRate) {
        Bank.interestRate = interestRate;
    }

    public static double getMinBalance() {
        return minBalance;
    }

    public static void setMinBalance(double minBalance) {
        Bank.minBalance = minBalance;
    }

二.单例(Singleton)设计模式

1.饿汉式

public class BankTest {
    public static void main(String[] args) {

        Bank bank1 = Bank.getInstance();
        Bank bank2 = Bank.getInstance();
        System.out.println(bank1 == bank2);
    }
}

//饿汉式
class Bank {
    //1. 类的构造器私有化
    private Bank() {
    }

    //2. 在类的内部创建当前类的实例
    //4. 此属性也必须声明为static的
    private static Bank instance = new Bank();

    //3. 使用getXxx()方法获取当前类的实例,必须声明为static的
    public static Bank getInstance() {
        return instance;
    }
}

2.懒汉式

public class GirlFriendTest {
    public static void main(String[] args) {
    }
}

//懒汉式
class GirlFriend {
    //1.类的构造器私有化
    private GirlFriend() {
    }
//2. 声明当前类的实例
//4. 此属性也必须声明为static的

    private static GirlFriend instance = null;

    //3. 通过getXxx()获取当前类的实例,如果未创建对象,则在方法内部进行创建
    public static GirlFriend getInstance() {
        if (instance == null) {
            instance = new GirlFriend();
        }
        return instance;
    }
}

对比

3.特点、优缺点

特点:

        饿汉式:“立即加载”,随着类的加载,当前的唯一实例就创建了

        懒汉式:"延迟加载",在需要使用的时候,进行创建。

优缺点:

        饿汉式:

                (优点)写法简单,由于内存中较早加载,使用更方便、更快。是线程安全的。                 (缺点)内存中 占用时间较长。 

        懒汉式:

                (缺点)线程不安全 (线程不安全 ,效率高)

                (优点)在需要的时候进行创建,节省内存空间。

三.代码块

3.1代码块(或初始化块)的作用: 

对 Java 类或对象进行初始化

3.2代码块(或初始化块)的分类

代码块只能被 static 修饰

被 static 修饰,称为静态代码块

没有使用 static 修饰的,为非静态代码块。 

3.3使用:

 静态代码块:

          随着类的加载而执行

         由于类的加载只会执行一次,进而静态代码块的执行,也只会执行一次

         作用:用来初始化类的信息

         内部可以声明变量、调用属性或方法、编写输出语句等操作。

         静态代码块的执行要先于非静态代码块的执行

         如果声明有多个静态代码块,则按照声明的先后顺序执行

         静态代码块内部只能调用静态的结构(即静态的属性、方法),不能调用非静态的结构(即非静态的属性,方法)

4.2 非静态代码块:

        随着对象的创建而执行

         每创建当前类的一个实例,就会执行一次非静态代码块

        作用:用来初始化对象的信息

         内部可以声明变量、调用属性或方法、编写输出语句等操作。

         如果声明有多个非静态代码块,则按照声明的先后顺序执行

         非静态代码块内部可以调用静态的结构(即静态的属性、方法),也可以调用非静态的结构(即非静态 的属性、方法) 

代码解析

public class BlockTest {
    public static void main(String[] args) {
        System.out.println(Person.info);
        System.out.println(Person.info);
        Person p1 = new Person();
        Person p2 = new Person();
        System.out.println(p1.age);//1
// p1.eat();
    }
}
class Person {
    String name;
    int age;
    static String info = "我是一个人";

    public void eat() {
        System.out.println("人吃饭");
    }

    public Person() {
    }

    //非静态代码块
    {
        System.out.println("非静态代码块2");
    }

    {
        System.out.println("非静态代码块1");
        age = 1;
        System.out.println("info = " + info);
    }

    //静态代码块
    static {
        System.out.println("静态代码块2");
    }

    static {
        System.out.println("静态代码块1");
        System.out.println("info = " + info);

    }
}

 

四..属性(实例变量)赋值

 4.1.给类的非静态的属性(实例变量)赋值的位置有:

① 默认初始化

② 显式初始化 或 ⑤ 代码块中初始化

③ 构造器中初始化 

④ 有了对象以后,通过"对象.属性"或"对象.方法"的方法进行赋值

4.2. 执行的先后顺序

① - ②/⑤ - ③ - ④ 

4.3.代码解析

public class FieldTest {
    public static void main(String[] args) {
        Order o1 = new Order();
        System.out.println(o1.orderId);//1
    }
}

class Order {
    int orderId = 1;

    {
        orderId = 2;
    }

    public Order() {
        super();
// orderId = 3;
    }

    public Order(int orderId) {
        this.orderId = orderId;
    }

    public void eat() {
        sleep();
    }

    public void sleep() {
    }
}

五.final关键字的使用

 5.1 final可以用来修饰的结构

类、方法、变量

final:最终的,(即不可以修改

 5.2final修饰

 final修饰类:表示此类不能被继承

比如:String、StringBuffer、StringBuilder类

final修饰方法:表示此方法不能被重写

比如:Object类中的getClass()

final修饰变量:既可以修饰成员变量,也可以修饰局部变量。

此时的"变量"其实就变成了"常量",意味着一旦赋值,就不可更改。

final与static搭配:修饰成员变量时,此成员变量称为:全局常量。(全局常量不可以修改)

5.3final与finally与finalize

final: 最终的,(即不可以修改

finally:异常try..catch..finally(解决异常错误

finalize:英语单词

六.抽象类与抽象方法 

6.1 abstract的概念

抽象的

6.2 abstract可以修饰

类、方法 

6.3语法格式

抽象类:被 abstract 修饰的类。

抽象方法:被 abstract 修饰没有方法体的方法。

抽象类的语法格式

        [权限修饰符] abstract class 类名{ }

        [权限修饰符] abstract class 类名 extends 父类{ }

抽象方法的语法格式

        [其他修饰符] abstract 返回值类型 方法名([形参列表]);

注意:抽象方法没有方法体

6.3abstract修饰类

        abstract修饰类,此类称为抽象类

        抽象类不能实例化。

        抽象类中是包含构造器的,因为子类对象实例化时,需要直接或间接的调用到父类的构造器。

        抽象类中可以没有抽象方法。有抽象方法所在的类,一定是抽象类。

6.4 abstract修饰方法

        abstract修饰方法此方法即为抽象方法

        抽象方法只有方法的声明,没有方法体

        抽象方法其功能是确定的(通过方法的声明即可确定),只是不知道如何具体实现(体现为没有方法 体)

        子类必须重写父类中的所有的抽象方法之后,方可实例化。否则,此子类仍然是一个抽象类。 

6.5abstract 不能修饰哪些结构

属性、构造器、代码块

 6.6 abstract 不能与哪些关键字共用

不能用abstract修饰私有方法、静态方法、final的方法、final的类。

        ①private修饰的方法,因为私有的方法是不能重写的。

        ②静态的方法,abstract修饰的方法是不应该被调用的,如果方法被static修饰,就可以通过类来进行调用。

        ③final修饰的方法,final修饰的方法是不能再重写的。

        ④final修饰的类,final修饰的类是不能被继承的。

 七.接口(interface)的使用

7.1接口的理解

接口的本质是契约、标准、规范,就像我们的法律一样。制定好后大家都要遵守。

即接口是一种规范

7.2接口内部结构的说明即格式

可以声明:

        属性:必须使用public static final修饰

        方法:jdk8之前:声明抽象方法,修饰为public abstract 

接口的声明格式

[修饰符] interface 接口名{

        //接口的成员列表:

        // 公共的静态常量

        // 公共的抽象方法

        // 公共的默认方法(JDK1.8 以上)

        // 公共的静态方法(JDK1.8 以上)

        // 私有方法(JDK1.9 以上)

}

7.3接口与类的关系即实现

实现关系 

实现格式:

         1.

        【修饰符】 class 实现类 implements 接口 1,接口 2,接口 3。。。{

                // 重写接口中所有抽象方法【必须】,当然如果实现类是抽象类,那么可以不重写

                // 重写接口中默认方法【可选】

         }

        2.

        【修饰符】 class 实现类 extends 父类 implements 接口 1,接口 2,接口 3。。。{

                // 重写接口中所有抽象方法【必须】,当然如果实现类是抽象类,那么可以不重写                 // 重写接口中默认方法【可选】

        }

接口中,有多个抽象方法时,实现类必须重写所有抽象方法。如果抽象方法有重名的,只需要重写一次

7.4格式

class A extends SuperA implements B,C{

}

A相较于SuperA来讲,叫做子类

A相较于B,C来讲,叫做实现类 

7.5接口作用

        类可以实现多个接口。

        类针对于接口的多实现,一定程度上就弥补了类的单继承的局限性。

        类必须将实现的接口中的所有的抽象方法都重写(或实现),方可实例化。否则,此实现类必须声明为抽象类。 

 7.6接口与接口的关系

继承关系,且可以多继承

7.7 接口的多态性

接口名 变量名 = new 实现类对象;

7.8抽象类和接口

共性:都可以声明抽象方法 都不能实例化

不同:

        ① 抽象类一定有构造器。接口没有构造器

        ② 类与类之间继承关系,类与接口之间是实现关系,接口与接口之间是多继承关系 

 7.9补充

①接口中声明的静态方法只能被接口来调用,不能使用其实现类进行调用
静态方法的声明:

public static void method1()//public可以省略
{
    System.out.println("这是静态方法");
}


②接口中声明的默认方法可以被实现类继承,实现类在没有实现此方法的情况下, 默认调用接口中声明的默认方法。如果重写了此方法,则调用的是重写后的方法。
默认方法的声明:

public default void method2()//public可以省略
{
    System.out.println("这是默认方法");
}

        注意:

        子接口重写默认方法时,default 关键字可以保留。

         子类重写默认方法时,default 关键字不可以保留。

public interface USB2 {
    //静态常量
    long MAX_SPEED = 60 * 1024 * 1024;//60MB/s

    //抽象方法
    void in();

    void out();

    //默认方法
    public default void start() {
        System.out.println("开始");
    }

    public default void stop() {
        System.out.println("结束");
    }

    //静态方法
    public static void show() {
        System.out.println("USB 2.0 可以高速地进行读写操作");
    }
}

public interface USB extends USB2, USB3 {
    @Override
    default void start() {
        System.out.println("Usb.start");
    }

    @Override
    default void stop() {
        System.out.println("Usb.stop");
    }
}


③如果类实现了两个接口,而两个方法中定义了同名同参数列表的默认方法。则实现类在没有重写此两个接口默认方法的情况下,会接口冲突(当一个类同时实现了多个父接口,而多个父接口中包含方法签名相同的默认方法)。 要求:此时实现类必须要重写接口中定义的同名同参数的方法。

解决方法:选择保留其中一个,通过“接口名.super.方法名"的方法选择保留哪个接口的默 认方法。

④子类(或实现类)继承了父类并实现了接口。父类和接口中声明了同名同参数的方法(其中,接口中的方法是默认方法). 默认情况下,子类(实现类)在没有重写此方法的情况下,调用的是父类中的方法。 ---- 类优先原则(当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口中的抽象方法重名,子类就近选择执行父类的成员方法。)

⑤如何在子类(实现类)中调用父类或接口中被重写的方法

method3();//调用自己类中的方法,省略了this.
super.method3();//调用父类中的方法
CompareA.super.method3();//调用接口CompareA中的默认方法
CompareB.super.method3();//调用接口CompareB中的默认方法

7.10总结

        接口本身不能创建对象,只能创建接口的实现类对象,接口类型的变量可以与实现类 对象构成多态引用。

        声明接口用 interface,接口的成员声明有限制:

                (1)公共的静态常量

                (2)公共的抽象方法

                (3)公共的默认方法(JDK8.0 及以上)

                (4)公共的静态方法(JDK8.0 及以上)

                (5)私有方法(JDK9.0 及以上)

        类可以实现接口,关键字是 implements,而且支持多实现。如果实现类不是抽象类, 就必须实现接口中所有的抽象方法。如果实现类既要继承父类又要实现父接口,那么继承(extends)在前,实现(implements)在后。

        接口可以继承接口,关键字是 extends,而且支持多继承。

        接口的默认方法可以选择重写或不重写。如果有冲突问题,另行处理。子类重写父接口的默认方法,要去掉 default,子接口重写父接口的默认方法,不要去掉 default。

        接口的静态方法不能被继承,也不能被重写。接口的静态方法只能通过“接口名.静态 方法名”进行调用。 

八.内部类

8.1内部类定义即格式

将一个类A定义在另一个类B里面,里面的那个类A就称为内部类(InnerClass),类B则称为外部类 (OuterClass)。

语法格式:

[修饰符] class 外部类{

        [其他修饰符] [static] class 内部类{ }

}

8.2分类

内部类的分类:

        成员内部类:直接声明在外部类的里面。

                使用static修饰的:静态的成员内部类

                不使用static修饰的:非静态的成员内部类

        局部内部类:声明在方法内、构造器内、代码块内的内部类

                匿名的局部内部类

                非匿名的局部内部类 

8.3成员内部类的理解+实例化静态内部类和实例化非静态

        从类的角度看:

                内部可以声明属性、方法、构造器、代码块、内部类等结构

                此内部类可以声明父类,可以实现接口

                可以使用final修饰

                 可以使用abstract修饰

        从外部类的成员的角度看:

                在内部可以调用外部类的结构。比如:属性、方法等

                可以使用public、缺省权限修饰之外,还可以使用private、protected修饰

                可以使用static修饰 

实例化静态内部类

        外部类名.静态内部类名 变量 = 外部类名.静态内部类名();

        变量.非静态方法();

实例化非静态内部类

        外部类名 变量 1 = new 外部类();

        外部类名.非静态内部类名 变量 2 = 变量 1.new 非静态内部类名();

        变量 2.非静态方法();

代码案列

public class TestMemberInnerClass {
    public static void main(String[] args) {
        //创建静态内部类实例,并调用方法
        Outer.StaticInner inner = new Outer.StaticInner();
        inner.inFun();
        //调用静态内部类静态方法
        Outer.StaticInner.inMethod();
        System.out.println("*****************************");

        //创建非静态内部类实例(方式 1),并调用方法
        Outer outer = new Outer();
        Outer.NoStaticInner inner1 = outer.new NoStaticInner();
        inner1.inFun();
        //创建非静态内部类实例(方式 2)
        Outer.NoStaticInner inner2 = outer.getNoStaticInner();
        inner1.inFun();
    }
}

class Outer {
    private static String a = "外部类的静态 a";
    private static String b = "外部类的静态 b";
    private String c = "外部类对象的非静态 c";
    private String d = "外部类对象的非静态 d";

    static class StaticInner {
        private static String a = "静态内部类的静态 a";
        private String c = "静态内部类对象的非静态 c";

        public static void inMethod() {
            System.out.println("Inner.a = " + a);
            System.out.println("Outer.a = " + Outer.a);
            System.out.println("b = " + b);
        }

        public void inFun() {
            System.out.println("Inner.inFun");
            System.out.println("Outer.a = " + Outer.a);
            System.out.println("Inner.a = " + a);
            System.out.println("b = " + b);
            System.out.println("c = " + c);
// System.out.println("d = " + d);//不能访问外部类的非静态成员
        }
    }

    class NoStaticInner {
        private String a = "非静态内部类对象的非静态 a";
        private String c = "非静态内部类对象的非静态 c";

        public void inFun() {
            System.out.println("NoStaticInner.inFun");
            System.out.println("Outer.a = " + Outer.a);
            System.out.println("a = " + a);
            System.out.println("b = " + b);
            System.out.println("Outer.c = " + Outer.this.c);
            System.out.println("c = " + c);
            System.out.println("d = " + d);
        }
    }

    public NoStaticInner getNoStaticInner() {
        return new NoStaticInner();
    }
}

8.4匿名(重要)

非匿名局部内部类语法格式

                [修饰符] class 外部类{

                [修饰符] 返回值类型 方法名(形参列表){

                 [final/abstract] class 内部类{ }

        }      

   }

匿名内部类格式

        new 父类([实参列表]){

                重写方法...

        }

        new 父接口(){

                重写方法...

        }

4种匿名方式 

1.提供了接口的实现类的对象

2.提供了接口的实现类的匿名对象

3.提供了接口的匿名实现类的对象

4.提供了接口的匿名实现类的匿名对象

个人理解  

代码解析 

public class OuterClassTest1 {
    //说明:局部内部类的使用
    public void method1() {
//局部内部类
        class A {
//可以声明属性、方法等
        }
    }

    //开发中的场景
    public Comparable getInstance() {
    //提供了实现了Comparable接口的类
    //方式1:提供了接口的实现类的对象
        class MyComparable implements Comparable {
            //
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }

        MyComparable m = new MyComparable();
        return m;
    //方式2:提供了接口的实现类的匿名对象
        class MyComparable implements Comparable {

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        }
        return new MyComparable();
    //方式3:提供了接口的匿名实现类的对象
        Comparable c = new Comparable() {
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
        return c;

    //方式4:提供了接口的匿名实现类的匿名对象
        return new Comparable() {
            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
    }
}

提供了接口的实现类的对象分析

提供了接口的实现类的匿名对象分析

 提供了接口的匿名实现类的对象分析

 提供了接口的匿名实现类的匿名对象分析

代码分析 

public class OuterClassTest2 {
    public static void main(String[] args) {
        SubA a = new SubA();
        a.method();
//举例1:提供接口匿名实现类的对象
        A a1 = new A() {
            public void method() {
                System.out.println("匿名实现类重写的方法method()");
            }
        };
        a1.method();
//举例2:提供接口匿名实现类的匿名对象
        new A() {
            public void method() {
                System.out.println("匿名实现类重写的方法method()");
            }
        }.method();
//举例3:
        SubB s1 = new SubB();
        s1.method1();
//举例4:提供了继承于抽象类的匿名子类的对象
        B b = new B() {
            public void method1() {
                System.out.println("继承于抽象类的子类调用的方法");
            }
        };
        b.method1();
        System.out.println(b.getClass());
        System.out.println(b.getClass().getSuperclass());
//举例5:
        new B() {
            public void method1() {
                System.out.println("继承于抽象类的子类调用的方法1");
            }
        }.method1();
    }
}

interface A {
    public void method();
}

class SubA implements A {
    @Override
    public void method() {
        System.out.println("SubA");
    }
}

abstract class B {
    public abstract void method1();
}

class SubB extends B {
    @Override
    public void method1() {
        System.out.println("SubB");
    }
}

class C {
    public void method2() {
        System.out.println("C");

    }
}
 提供接口匿名实现类的对象分析

提供接口匿名实现类的匿名对象分析
 提供了继承于抽象类的匿名子类的对象分析

九.枚举类 

9.1使用

如果针对于某个类,其实例是确定个数的。则推荐将此类声明为枚举类。

如果枚举类的实例只有一个,则可以看做是单例的实现方式。

 9.2jdk5.0之前,使用自定义枚举类的方法。步骤如下:

1. 私有化类的构造器
2. 声明当前类的对象的实例变量 , 要用 final 修饰
3. 提供 get 方法
4. 创建类的实例要用 psf ( public static final )修饰,变为全局常量

//自定义枚举类
class Season{
    //2.声明当前类的对象的实例变量,要用final修饰
    private final String seasonName;//季节的名称
    private final String seasonDesc;//季节的描述
    //1.私有化类的构造器
    private Season(String seasonName,String seasonDesc)
    {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
    //3.提供get方法
    public String getSeasonName()
    {
        return seasonName;
    }
 
    public String getSeasonDesc()
    {
        return seasonDesc;
    }
    //4.创建类的实例//要用psf(public static final)修饰,变为全局常量
    public static final Season Spring = new Season("春天","花开的季节");
    public static final Season Summer = new Season("夏天","炎热的季节");
    public static final Season Autumn = new Season("秋天","丰收的季节");
    public static final Season Winter = new Season("冬天","寒冷的季节");
 
 
    @Override
    public String toString()
    {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}

9.3在jdk5.0时,加入使用 enum定义枚举类。步骤如下:

1. 创建对象,必须在枚举类的开头声明多个对象。对象之间使用逗号隔开。
2. 声明当前类的对象的实例变量 , 要用 final 修饰
3. 私有化类的构造器
3. 提供 get 方法

格式:

        【修饰符】 enum 枚举类名{

                常量对象列表

                }

        【修饰符】 enum 枚举类名{

                常量对象列表;

                对象的实例变量列表;

}

要求

        枚举类的常量对象列表必须在枚举类的首行,因为是常量,所以建议大写。

        列出的实例系统会自动添加 public static final 修饰。

        如果常量对象列表后面没有其他代码,那么“;”可以省略,否则不可以省略“;”。

         编译器给枚举类默认提供的是 private 的无参构造,如果枚举类需要的是无参构造, 就不需要声明,写常量对象列表时也不用加参数

        如果枚举类需要的是有参构造,需要手动定义,有参构造的 private 可以省略,调用 有参构造的方法就是在常量对象名后面加(实参列表)就可以。

        枚举类默认继承的是 java.lang.Enum 类,因此不能再继承其他的类型。

        JDK5.0 之后 switch,提供支持枚举类型,case 后面可以写枚举常量名,无需添加枚举类作为限定。

public enum Week {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
}

public class TestEnum {
    public static void main(String[] args) {
        Season spring = Season.SPRING;
        System.out.println(spring);
    }
}
//jdk5.0中使用enum关键字定义枚举类
 
enum Season1
 
{
    //1.创建对象,必须在枚举类的开头声明多个对象。对象之间使用逗号隔开。
 
    Spring("春天","花开的季节"),
 
    Summer("夏天","炎热的季节"),
 
    Autumn("秋天","丰收的季节"),
 
    Winter("冬天","寒冷的季节");
 
    //2.声明当前类的对象的实例变量,要用final修饰
 
    private final String seasonName;//季节的名称
 
    private final String seasonDesc;//季节的描述
 
    //3.私有化类的构造器
 
    private Season1(String seasonName,String seasonDesc)
 
    {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
 
    //3.提供get方法
 
    public String getSeasonName()
 
    {
        return seasonName;
    }
 
  
    public String getSeasonDesc()
 
    {
        return seasonDesc;
    }
 
}

9.4Enum类中常用的方法

①使用enum定义的枚举类,默认其父类是java.lang.Enum类。(所以不能再定义其他父类)
②Enum类中的常用方法:
                (如果sout输出为对象名,即默认为调用对象名.toString( )方法)
        String  toString( ) : 默认返回的是常量名(对象名),可以继续手动重写该方法。
        String  name( ) : 默认返回当前枚举对象的名称,当toString被重写了,想获得枚举类对象的名称,即用name( )
         static  枚举类型[ ] values( ) : 返回枚举类型的对象数组。该方法可以很方便的遍历所有的枚举值,为静态方法。

        int ordinal():返回当前枚举常量的次序号,默认从0开始

9.5枚举类实现接口

情况①:枚举类实现接口,在枚举类中重写接口中的抽象方法。当通过不同的枚举类的对象调用此方法时,执行的时是一个方法。
情况②:枚举类实现接口,在枚举类的每个对象中重写接口中的方法。操作:在对象后面加上{},在{}里面重写接口中的方法,即为在对象中重写接口中的方法。

语法:

        1、枚举类可以像普通的类一样,实现接口,并且可以多个,但要求必须实现里面所有的抽象方法!

                 enum A implements 接口 1,接口 2{

                        抽象方法的实现

                 } 

        2、如果枚举类的常量可以继续重写抽象方法!

                 enum A implements 接口 1,接口 2{

                        常量名 1(参数){

                         抽象方法的实现或重写

                        },

                        常量名 2(参数){

                        抽象方法的实现或重写 },

                        ........         

                        }

public class SeasonTest2
{
 
}
 
 
interface Info
{
    void show();
}
enum Season2 implements Info
{
    //1.创建对象,必须在枚举类的开头声明多个对象。对象之间使用逗号隔开。
    Spring("春天","花开的季节"){
        public void show()
        {
            System.out.println("春");
        }
    },
    Summer("夏天","炎热的季节"){
        public void show()
        {
            System.out.println("夏");
        }
    },
    Autumn("秋天","丰收的季节"){
        public void show()
        {
            System.out.println("秋");
        }
    },
    Winter("冬天","寒冷的季节"){
        public void show()
        {
            System.out.println("冬");
        }
    };
    //2.声明当前类的对象的实例变量,要用final修饰
    private final String seasonName;//季节的名称
    private final String seasonDesc;//季节的描述
    //3.私有化类的构造器
    private Season2(String seasonName,String seasonDesc)
    {
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
    //3.提供get方法
    public String getSeasonName()
    {
        return seasonName;
    }
 
 
    public String getSeasonDesc()
    {
        return seasonDesc;
    }
 
 
    @Override
    public String toString()
    {
        return "Season2{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}

 十.包装类

10.1为什么要使用包装类?

为了使得基本数据类型的变量具备引用数据类型变量的相关特征(比如:封装性、继承性、多态性),我们给各 个基本数据 类型的变量都提供了对应的包装类。

10.2基本数据类型对应的包装类类型

byte -> Byte

short -> Short

int -> Integer

long -> Long

float -> Float

double ->Double

char -> Character

boolean -> Boolean 

10.3自定义包装类

public class MyInteger {
    int value;

    public MyInteger() {
    }

    public MyInteger(int value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return String.valueOf(value);
    }
}

10.4装箱

把基本数据类型转为包装类对象 转为包装类的对象,是为了使用专门为对象设计的 API 和特性

基本数值---->包装对象

基本数据类型 ---> 包装类:

① 使用包装类的构造器

② (建议)调用包装类的valueOf(xxx xx)

Integer obj1 = new Integer(4);//使用构造函数函数
Float f = new Float(“4.56”);
Long l = new Long(“asdf”); //NumberFormatException
Integer obj2 = Integer.valueOf(4);//使用包装类中的 valueOf 方法
Integer i = 4;//自动装箱。相当于 Integer i = Integer.valueOf(4);
//自动装箱: 基本数据类型 ---> 包装类
int i1 = 10;
Integer ii1 = i1; //自动装箱
System.out.println(ii1.toString());
Integer ii2 = i1 + 1; //自动装箱
Boolean bb1 = true;//自动装箱
Float f1 = 12.3F; //自动装箱
//自动拆箱:包装类 ---> 基本数据类型
int i2 = ii1; //自动拆箱
boolean b1 = bb1;//自动拆箱

10.5拆箱

把包装类对象拆为基本数据类型 转为基本数据类型,一般是因为需要运算,Java 中的大多数运算符是 为基本数据类型设计的。比较、算术等 

包装对象---->基本数值

包装类 ---> 基本数据类型:调用包装类的xxxValue()

包装类 ---> 基本数据类型:调用包装类的xxxValue()

Integer obj = new Integer(4);
int num1 = obj.intValue();
i = i + 5;//等号右边:将 i 对象转成基本数值(自动拆箱) i.intValue() + 5;
//加法运算完成后,再次装箱,把基本数值转成对象。
//推荐使用:
int i2 = 10;
Integer ii2 = Integer.valueOf(i2);
Boolean b2 = Boolean.valueOf(true);
Float f2 = Float.valueOf(12.3F);

10.6基本数据类型、包装类与字符串间的转换 

常用:String类型 ---> 基本数据类型、包装类: 调用包装类的静态方法:parseXxx()

10.61基本数据类型转为字符串

        方式 1:调用字符串重载的 valueOf()方法

int a = 10;
//String str = a;//错误的
String str = String.valueOf(a);

方式 2:自动类型提升

int a = 10;
String str = a + "";

 10.62 字符串转为基本数据类型

常用:基本数据类型、包装类 ---> String类型:

① 调用String的重载的静态方法valueOf(xxx xx) ;

② 基本数据类型的变量 + ""

方式 1:使用 parseXxx 静态方法将字符串参数转换为对应的基本类型(除了 Character 类)

public static int parseInt(String s):将字符串参数转换为对应的 int 基 本类型。

public static long parseLong(String s):将字符串参数转换为对应的 long 基本类型。

public static double parseDouble(String s):将字符串参数转换为对应的 double 基本类型。

方式 2:字符串转为包装类,然后可以自动拆箱为基本数据类型

 • public static Integer valueOf(String s):将字符串参数转换为对应的 Integer 包装类,然后可以自动拆箱为 int 基本类型

public static Long valueOf(String s):将字符串参数转换为对应的 Long 包装类,然后可以自动拆箱为 long 基本类型

public static Double valueOf(String s):将字符串参数转换为对应的 Double 包装类,然后可以自动拆箱为 double 基本类型

方式 3:通过包装类的构造器实现 
int a = Integer.parseInt("整数的字符串");
double d = Double.parseDouble("小数的字符串");
boolean b = Boolean.parseBoolean("true 或 false");
int a = Integer.valueOf("整数的字符串");
double d = Double.valueOf("小数的字符串");
boolean b = Boolean.valueOf("true 或 false");
int i = new Integer(“12”);

10.7总结 

十一.进制转换

11.1十进制转二进制

Integer.toBinaryString(int i)

int decimal = 10;
String binary = Integer.toBinaryString(decimal);
System.out.println("Binary: " + binary);

输出:Binary: 1010

11.2十进制转八进制 

Integer.toOctalString(int i)

int decimal = 10;
String octal = Integer.toOctalString(decimal);
System.out.println("Octal: " + octal);

输出:Octal: 12

11.3十进制转十六进制

Integer.toHexString(int i)

int decimal = 10;
String hexadecimal = Integer.toHexString(decimal);
System.out.println("Hexadecimal: " + hexadecimal);

输出:Hexadecimal: a

11.4任意进制转换

Integer.toString(int i, int radix)方法将十进制数decimal转换为指定进制radix的字符串表示 

 int decimal = 10;
        int radix = 5;
        String customRadix = Integer.toString(decimal, radix);
        System.out.println("Custom Radix: " + customRadix);
    

Custom Radix: 20

十二.大小写转化

12.1小写字母转大写字母

Character.toUpperCase(char ch) 

char lowerCase = 'a';
char upperCase = Character.toUpperCase(lowerCase);
System.out.println("Upper Case: " + upperCase);

输出:Upper Case: A

 12.2大写字母转小写字母

Character.toLowerCase(char ch)

char upperCase = 'A';
char lowerCase = Character.toLowerCase(upperCase);
System.out.println("Lower Case: " + lowerCase);

输出:Lower Case: a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值