【JavaSE】基础知识复习 (二)

目录

1.面向对象

对象内存分析

类的成员

类成员之一:成员变量

成员变量声明

成员变量 vs 局部变量

类成员之二:方法

方法调用内存分析

方法重载 (overload)

可变形参

方法递归

注意

类成员之三:构造器

语法格式

特点

this()

注意点

类成员之四:代码块

静态代码块

特点

非静态代码块

特点

面向对象特征

面向对象特征之一:封装性

"高内聚、低耦合"

什么是封装性?

面向对象特征之二:继承

继承性

方法重写 (override/overwrite)

方法重写的要求

跨包必须pulbic

super

调用父类被重写的方法

调用父类中同名的成员变量

子类构造器调用父类构造器

小结:this与super

this 和 super的使用格式

面向对象特征之三:多态

多态的理解

运行时、编译时

多态的好处/弊端

开闭原则 OCP

虚方法调用

成员变量没有多态性

向上/下转型

为什么要类型转换?

如何向下/上转型?

instanceof关键字

Object根父类

Object类的方法

(重点)equals()

(重要)toString()

clone()

finalize()

getClass()

hashCode()

native关键字

static关键字

类属性、类方法的设计思想

静态变量

静态方法

单例(Singleton)设计模式

设计模式

何为单例模式?

饿汉式

懒汉式

懒汉式 VS 饿汉式

单例模式的优点及应用场景

main方法如何理解?

final关键字

final修饰类 (太监类)

final修饰方法

final修饰变量

抽象类与抽象方法 (abstract关键字)

理解抽象类

语法格式

使用说明

注意事项

抽象类中可以定义构造方法吗?

模板方法设计模式

接口

声明格式

接口成员

使用规则

类实现接口

接口的多实现

接口的多继承

接口与实现类对象构成多态引用

使用接口的静态成员

使用接口的非静态方法

JDK8中相关冲突问题

默认方法冲突原则

(1)类优先原则

(2)接口冲突(左右为难)

常量冲突问题

接口的总结

abstract与interface

不同点

相同点

内部类

分类

成员内部类

使用规则

创建成员内部类对象

局部内部类

非匿名局部内部类

匿名内部类

枚举类

定义枚举类

JDK5之前

JDK5之后

ENUM定义的要求和特点

ENUM中常用方法

实现接口的枚举类

语法

注解

注解与注释

注解的重要性

常见的注解作用

三个最基本的注解

元注解

自定义注解(未完)

JUnit单元测试(未完)

测试分类

JUnit单元测试介绍

JUnit使用

JUnit4.x版本要求

创建Maven JavaSE项目

导入依赖

包装类

包装类与基本数据类型的转换

装箱

拆箱

自动装箱与自动拆箱

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

(1)基本数据类型转字符串

(2)字符串转基本数据类型

​编辑其他方式小结

包装类的其他API

数据类型的最值

字符转大小写

整数转进制

比较的方法

包装类对象特点

包装类缓存对象

类型转换问题

包装类对象不可变

Java17版本的包装类


1.面向对象

对象内存分析

举例:

class Person { //类:人
  String name;
  int age;
  boolean isMale;
}
public class PersonTest { //测试类
    public static void main(String[] args) {
    Person p1 = new Person();
    p1.name = "赵同学";
    p1.age = 20;
    p1.isMale = true;
    Person p2 = new Person();
    p2.age = 10;
    Person p3 = p1;
    p3.name = "郭同学";
  }
}

内存分析图:

类的成员

类成员之一:成员变量
成员变量声明

成员变量 vs 局部变量

类成员之二:方法
方法调用内存分析

举例:

        public class Person {
            public static void main(String[] args) {
                Person p1 = new Person();
                p1.eat();
            }
            public static void eat() {
                sleep();
                System.out.println("人:吃饭");
            }
            public static void sleep(){
                System.out.println("人:睡觉");
                doSport();
            }
            public static void doSport(){
                System.out.println("人:运动");
            }
        }

方法重载 (overload)

最经典的方法重载案例

可变形参

方法递归

递归方法调用:方法自己调用自己的现象就称为递归。

  • 递归方法包含了一种隐式的循环。
  • 递归方法会重复执行某段代码,但这种重复执行无须循环控制。
  • 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,停不下来,类似于死循 环。最终发生栈内存溢出。

递归的分类: 直接递归、间接递归。

注意


类成员之三:构造器

语法格式

特点
  • 如果没有显式手动声明类的构造器时,系统会默认提供一个无参构造器,且该构造器的修饰符与默认与类的修饰符相同
  • 如果显式定义类的构造器后,系统就不会再提供默认的无参构造器了
  • 在类中,至少会存在一个构造器
  • 构造器是可以重载的
this()

同一个类中构造器互相调用

注意点

类成员之四:代码块

静态代码块

特点

public class Chinese {
    // private static String country = "中国";
     private static String country;
     private String name;
     {
         System.out.println("非静态代码块,country = " + country);
     }
     static {
         country = "中国";
         System.out.println("静态代码块");
     }
     public Chinese(String name) {
         this.name = name;
     }
}
public class TestStaticBlock {
     public static void main(String[] args) {
         Chinese c1 = new Chinese("张三");
         Chinese c2 = new Chinese("李四");
     }
}
非静态代码块

特点

 

面向对象特征

面向对象特征之一:封装性

"高内聚、低耦合"

什么是封装性?

通俗的讲,把该隐藏的隐藏起来,该暴露的暴露出来。这就是封装性的设计思 想。

面向对象特征之二:继承
继承性

方法重写 (override/overwrite)

方法重写的要求

跨包必须pulbic

super

调用父类被重写的方法

调用父类中同名的成员变量

子类构造器调用父类构造器

小结:this与super

this 和 super的使用格式

面向对象特征之三:多态

一千个读者眼中有一千个哈姆雷特。

父类当形参 子类当实参

【每天一个技术点】多态,多么变态_哔哩哔哩_bilibili

我理解的多态

我理解的多态,一个具体类实现了父类animal,也实现了接口flyable, runnable jumpable, 那实际应用过程中,这个具体类你在需要他是animal的时候他就是animal,是flyable的时候他就是flyable,还是is a 原则,但多种is a 都可以同时成立=>多态

多态的理解

运行时、编译时

多态的好处/弊端

开闭原则 OCP

虚方法调用

成员变量没有多态性

向上/下转型

为什么要类型转换?

如何向下/上转型?

instanceof关键字

Object根父类
Object类的方法

根据 JDK 源代码及 Object 类的 API 文档,Object 类当中包含的方法有 11 个。

这里我们主要关注其中的 6 个:

(重点)equals()

(重要)toString()

clone()

public static void main(String[] args) {
    Animal a1 = new Animal("花花");
    try {
        Animal a2 = (Animal) a1.clone();
        System.out.println("原始对象:" + a1);
        a2.setName("毛毛");
        System.out.println("clone 之后的对象:" + a2);
    } catch (CloneNotSupportedException e) {
        e.printStackTrace();
    }
}
class Animal implements Cloneable{
    private String name;
    public Animal() {
        super();
    }
    public Animal(String name) {
        super();
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Animal [name=" + name + "]";
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        return super.clone();
    }
}
finalize()

在 JDK 9 中此方法已经被标记为过时的。

public class FinalizeTest {
    public static void main(String[] args) {
        Person p = new Person("Peter", 12);
        System.out.println(p);
        p = null;//此时对象实体就是垃圾对象,等待被回收。但时间不确定。
        System.gc();//强制性释放空间
    }
}
class Person{
    private String name;
    private int age;
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    //子类重写此方法,可在释放对象前进行某些操作
    @Override
    protected void finalize() throws Throwable {
        System.out.println("对象被释放--->" + this);
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}
getClass()

hashCode()

native关键字

static关键字

如果想让一个成员变量被类的所有实例所共享,就用 static 修饰即可,称为类 变量(或类属性)!

类属性、类方法的设计思想

静态变量

静态方法

单例(Singleton)设计模式
设计模式

何为单例模式?

饿汉式

无论用不用得到,总会加载一个实例,就像吃货的身上总会带着食物

饿汉式是一种在类加载时就创建实例的单例模式。它的特点是无论是否会被使用到,实例对象都在类加载时被创建。

class Singleton {
     // 1.私有化构造器
     private Singleton() {
     }
     // 2.内部提供一个当前类的实例
     // 4.此实例也必须静态化
     private static Singleton single = new Singleton();
     // 3.提供公共的静态的方法,返回当前类的对象
     public static Singleton getInstance() {
         return single;
     }
}
懒汉式

不需要的时候懒得加载实例,用到的时候才加载实例,默认为null

  • 懒汉式属于一种延迟加载的单例模式,它的特点是在第一次使用时创建实例对象,而不是在类加载时就创建。
  • 懒汉式可以避免在不需要实例对象时的资源浪费,只有在需要时才进行创建。这种延迟加载的特性使得它在某些情况下更加高效。
class Singleton {
     // 1.私有化构造器
     private Singleton() {
     }
     // 2.内部提供一个当前类的实例
     // 4.此实例也必须静态化
     private static Singleton single;
     // 3.提供公共的静态的方法,返回当前类的对象
     public static Singleton getInstance() {
         if(single == null) {
             single = new Singleton();
         }
         return single;
     }
}
懒汉式 VS 饿汉式

单例模式的优点及应用场景

main方法如何理解?

 


final关键字

final:最终的,不可更改的

final修饰类 (太监类)

final修饰方法

final修饰变量

抽象类与抽象方法 (abstract关键字)
理解抽象类

语法格式

使用说明

注意事项

抽象类中可以定义构造方法吗?

模板方法设计模式

abstract class Template {
     public final void getTime() {
         long start = System.currentTimeMillis();
         code();
         long end = System.currentTimeMillis();
         System.out.println("执行时间是:" + (end - start));
     }
     public abstract void code();
}
class SubTemplate extends Template {
     public void code() {
         for (int i = 0; i < 10000; i++) {
             System.out.println(i);
         }
     }
}
接口
声明格式

接口成员
  • Java8之前,接口只能写 公共的抽象方法 公共的静态常量
  • Java8开始,接口引入了 默认方法静态方法 的概念,这两种方法都可以有方法体不需要实现类去实现默认方法可以被实现类重写,静态方法则不能被实现类直接使用,只能被接口自身调用

        这两种方法的引入解决了接口升级和维护的问题,‌使得接口可以更加灵活地扩展功能

  • Java9开始,接口还可以定义私有方法,这些私有方法只能被接口内部的其他方法调用,本能被接口的实现类直接访问和调用

使用规则
类实现接口

接口的多实现

接口的多继承
  • 一个接口能继承另一个或者多个接口,接口的继承也使用 extends 关键字,子 接口继承父接口的方法。
  • 所有父接口的抽象方法都有重写。
  • 方法签名相同的抽象方法只需要实现一次。
public interface Chargeable {
     void charge();
     void in();
     void out();
}
定义子接口:
public interface UsbC extends Chargeable,USB3 {
     void reverse();
}
定义子接口的实现类:
public class TypeCConverter implements UsbC {
     @Override
     public void reverse() {
         System.out.println("正反面都支持");
     }
     @Override
     public void charge() {
         System.out.println("可充电");
     }
     @Override
     public void in() {
         System.out.println("接收数据");
     }
     @Override
     public void out() {
         System.out.println("输出数据");
     }
}
接口与实现类对象构成多态引用

使用接口的静态成员

接口不能直接创建对象,但是可以通过接口名直接调用接口的静态方法和静态 常量。

使用接口的非静态方法

JDK8中相关冲突问题
默认方法冲突原则
(1)类优先原则

当一个类,既继承一个父类,又实现若干个接口时,父类中的成员方法与接口 中的抽象方法重名,子类就近选择执行父类的成员方法。

(2)接口冲突(左右为难)
  • 当一个类同时实现了多个父接口,而多个父接口中包含方法签名相同的默认方法时, 怎么办呢?无论你多难抉择,最终都是要做出选择的。

解决办法:子类通过接口名.super.方法名()区分

-----------------------------------------------------------------------------------------------------------------------

  • 当一个子接口同时继承了多个接口,而多个父接口中包含方法签名相同的默认方法 时,怎么办呢?

解决办法:子接口通过重写默认方法区分

常量冲突问题

接口的总结

abstract与interface

不同点
  • 核心区别

核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法,子类必须重写所有的抽象方法。

相同点

// 抽象类
abstract class Animal {
    abstract void makeSound();
}
 
// 实现抽象类
class Dog extends Animal {
    void makeSound() {
        System.out.println("Woof!");
    }
}
 
// 接口
interface Flyable {
    void fly();
}
 
// 实现接口
class Bird implements Flyable {
    void fly() {
        System.out.println("I'm flying!");
    }
}
 
public class Main {
    public static void main(String[] args) {
        Animal dog = new Dog();
        dog.makeSound(); // 输出: Woof!
 
        Bird bird = new Bird();
        bird.fly(); // 输出: I'm flying!
    }
}
内部类

分类

成员内部类

使用规则

创建成员内部类对象

    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();
        }
    }
局部内部类
非匿名局部内部类

public class TestLocalInner {
        public static void main(String[] args) {
            Outer.outMethod();
            System.out.println("-------------------");
            Outer out = new Outer();
            out.outTest();
            System.out.println("-------------------");
            Runner runner = Outer.getRunner();
            runner.run();
        }
    }
    class Outer{
        public static void outMethod(){
            System.out.println("Outer.outMethod");
            final String c = "局部变量 c";
            class Inner{
                public void inMethod(){
                    System.out.println("Inner.inMethod");
                    System.out.println(c);
                }
            }
            Inner in = new Inner();
            in.inMethod();
        }
        public void outTest(){
            class Inner{
                public void inMethod1(){
                    System.out.println("Inner.inMethod1");
                }
            }
            Inner in = new Inner();
            in.inMethod1();
        }
        public static Runner getRunner(){
            class LocalRunner implements Runner{
                @Override
                public void run() {
                    System.out.println("LocalRunner.run");
                }
            }
            return new LocalRunner();
        }
    }
    interface Runner{
        void run();
    }
匿名内部类

枚举类

开发中,当需要定义一组常量时,强烈建议使用枚举类。

定义枚举类
JDK5之前

JDK5之后

ENUM定义的要求和特点

ENUM中常用方法

import java.util.Scanner;
public class TestEnumMethod {
    public static void main(String[] args) {
        //values()
        Week[] values = Week.values();
        for (int i = 0; i < values.length; i++) {
            //ordinal()、name()
            System.out.println((values[i].ordinal()+1) + "->" + values
                    [i].name());
        }
        System.out.println("------------------------");
        Scanner input = new Scanner(System.in);
        System.out.print("请输入星期值:");
        int weekValue = input.nextInt();
        Week week = values[weekValue-1];
        //toString()
        System.out.println(week);
        System.out.print("请输入星期名:");
        String weekName = input.next();
        //valueOf()
        week = Week.valueOf(weekName);
        System.out.println(week);
        input.close();
    }
}
实现接口的枚举类

语法

interface Info{
    void show();
}
//使用 enum 关键字定义枚举类
enum Season1 implements Info{
    //1. 创建枚举类中的对象,声明在 enum 枚举类的首位
    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("2002 年的第一场雪");
        }
    };
    //2. 声明每个对象拥有的属性:private final 修饰
    private final String SEASON_NAME;
    private final String SEASON_DESC;
    //3. 私有化类的构造器
    private Season1(String seasonName,String seasonDesc){
        this.SEASON_NAME = seasonName;
        this.SEASON_DESC = seasonDesc;
    }
    public String getSEASON_NAME() {
        return SEASON_NAME;
    }
    public String getSEASON_DESC() {
        return SEASON_DESC;
    }
}
注解

注解与注释

注解的重要性

常见的注解作用

三个最基本的注解

import java.util.ArrayList;
public class TestAnnotation {
    @SuppressWarnings("all")
    public static void main(String[] args) {
        int i;
        ArrayList list = new ArrayList();
        list.add("hello");
        list.add(123);
        list.add("world");
        Father f = new Son();
        f.show();
        f.methodOl();
    }
}
class Father{
    @Deprecated
    void show() {
        System.out.println("Father.show");
    }
    void methodOl() {
        System.out.println("Father Method");
    }
}
class Son extends Father{
/* @Override
void method01() {
System.out.println("Son Method");
}*/
}
元注解

import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
package java.lang;
        import java.lang.annotation.*;
        import static java.lang.annotation.ElementType.*;
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABL
        E})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}
package java.lang;
        import java.lang.annotation.*;
        import static java.lang.annotation.ElementType.*;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, P
        ARAMETER, TYPE})
public @interface Deprecated {
}
自定义注解(未完)

Java 实现自定义注解_java自定义注解-CSDN博客

JUnit单元测试(未完)
测试分类

JUnit单元测试介绍

JUnit使用
JUnit4.x版本要求

创建Maven JavaSE项目

导入依赖

junit-4.12.jar
//junit-4.11之后需要自己导入该包
hamcrest-core-1.3.jar

<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-core -->
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest-core</artifactId>
    <version>1.3</version>
    <scope>test</scope>
</dependency>
包装类

包装类与基本数据类型的转换
装箱

拆箱

自动装箱与自动拆箱

基本数据类型、包装类与字符串的转换
(1)基本数据类型转字符串

(2)字符串转基本数据类型

其他方式小结

包装类的其他API
数据类型的最值

字符转大小写

整数转进制

比较的方法

包装类对象特点
包装类缓存对象

Double和Float不缓存对象,存的地址,只比较地址

类型转换问题

包装类对象不可变
public class TestExam {
    public static void main(String[] args) {
        int i = 1;
        Integer j = new Integer(2);
        Circle c = new Circle();
        change(i,j,c);
        System.out.println("i = " + i);//1
        System.out.println("j = " + j);//2
        System.out.println("c.radius = " + c.radius);//10.0
    }
    /*
    * 方法的参数传递机制:
    * (1)基本数据类型:形参的修改完全不影响实参
    * (2)引用数据类型:通过形参修改对象的属性值,会影响实参的属性值
    * 这类 Integer 等包装类对象是“不可变”对象,即一旦修改,就是新对象,和
    实参就无关了
    */
    public static void change(int a ,Integer b,Circle c ){
        a += 10;
// b += 10;//等价于 b = new Integer(b+10);
        c.radius += 10;
/*c = new Circle();
c.radius+=10;*/
    }
}
class Circle{
    double radius;
}
Java17版本的包装类

不知道哪个版本开始,这个被弃用且移除了

下一章:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值