java学习笔记7——面向对象

news2025/4/1 15:01:58

关键字:static

类变量

静态变量的内存解析:

相关代码:

public class ChineseTest {
    public static void main(String[] args) {
        System.out.println(Chinese.nation); //null 没赋值前
        System.out.println(Chinese.nation); //中国 静态变量赋值之后
        Chinese c1 = new Chinese();
        c1.name = "姚明";
        c1.age = 40;
        c1.nation = "China";

        Chinese c2 = new Chinese();
        c2.name = "刘翔";
        c2.age = 39;
        System.out.println(c1);
        System.out.println(c2);

        System.out.println(c1.nation); // China
        System.out.println(c2.nation); // China

        c2.nation = "CHN";
        System.out.println(c1.nation); // CHN
        System.out.println(c2.nation); // CHN
    }
}
class Chinese { //中国人类
    //非静态变量、实例变量
    String name;
    int age;

    //静态变量、类变量
    /**
     * China
     * China
     * CHN
     * CHN
     */
    static String nation = "中国";
    /**
     * China
     * null
     * China
     * CHN
     */
//    String nation;

    @Override
    public String toString() {
        return "Chinese{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

类方法(class method)

案例1:

编写一个类实现银行账户的概念,包含的属性有“帐号”、“密码”、“存款余额"、“利率"、“最小余额",
定义封装这些属性的方法,账号要自动生成。

编写主类,使用银行账户类,输入、输出3个储户的上述信息。

考虑:哪些属性可以设计成static属性x

相关代码:

AccountTest 
public class AccountTest {
    public static void main(String[] args) {
        Account acct1 = new Account();
        System.out.println(acct1);
        Account acct2 = new Account("123456", 2000);
        System.out.println(acct2);
        Account.setInterestRate(0.0123);
        Account.setMinBalance(10);
        System.out.println("银行存款的利率为:" + Account.getInterestRate());
        System.out.println("银行存款的额度为:" + Account.getMinBalance());

    }
}
Account 
public class Account {
    private int id; //账号
    private String password; //密码
    private double balance; //余额
    private static double interestRate; //利率
    private static double minBalance = 1.0; //最小余额
    private static int init = 1001; //用于自动生成id的基数
    public Account(){
        this.id = init;
        init++;
        password = "000000";
    }

    public Account(String password, double balance) {
        this.password = password;
        this.balance = balance;
        this.id = init;
        init++;
    }

    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) {
        Account.interestRate = interestRate;
    }

    public static double getMinBalance() {
        return minBalance;
    }

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

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", password='" + password + '\'' +
                ", balance=" + balance +
                '}';
    }
}

面试题:

public class StaticTest {
    public static void main(String[] args) {
        Order order = null;
        //可以打印出来,静态并不依赖于对象,直接通过类调用即可
        order.hello(); //hello!
        System.out.println(order.count); //1
    }
}
class Order{
    public static int count = 1;
    public static void hello() {
        System.out.println("hello!");
    }
}

本章总结:

static关键字的使用

1. static:静态的

2.static 用来修饰的结构:属性、方法;代码块、内部类

3.static修饰属性
    3.1 复习:变量的分类
    方式1:按照数据类型:基本数据类型、引用数据类型

    方式2:按照类中声明的位置
        成员变量:按照是否使用static修饰进行分类:
            使用static修饰的成员变量:静态变量、类变量
            不使用static修饰的成员变量:非静态变量、实例变量

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

    3.2 静态变量:类中的属性使用static进行修饰。
        对比静态变量与实例变量:
        ① 个数
            > 静态变量: 内存空间中只有一份,被类的多个对象所共享。
            > 实例变量: 类的每一个实例(或对象)都保存着一份实例变量。
        ② 内存位置
            > 静态变量: jdk6及之前:存放在方法区。jdk7之后:存放在堆空间
            > 实例变量: 存放在堆空间的对象实体中
        ③ 加载时机
            > 静态变量: 随着类的加载而加载,由于类只会加载一次,所以静态变量也只有一份。
            > 实例变量: 随着对象的创建而加载。每个对象拥有一份实例变量。
        ④ 调用者
            > 静态变量: 可以被类直接调用,也可以使用对象调用。
            > 实例变量: 只能使用对象进行调用。
        ⑤ 判断是否可以调用 ---> 从生命周期的角度解释
                        类变量             实例变量
           类             yes                no
           对象           yes                yes

        ⑥ 消亡时机
            > 静态变量: 随着类的卸载而消亡
            > 实例变量: 随着对象的消亡而消亡


4.static修饰方法:(类方法、静态方法)

> 随着类的加载而加载
> 可以通过"类.静态方法"的方式,直接调用静态方法
> 静态方法内可以调用静态的属性或静态的方法(属性和方法的前缀使用的是当前类,可以省略)
        不可以调用非静态的结构。(比如:属性、方法)

                      类变量             实例变量
        类             yes                no
        对象           yes                yes
> static修饰的方法内,不能使用this和super

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

5.开发中,什么时候需要将属性声明为静态的?
    > 判断当前类的多个实例是否能共享此成员变量,且此成员变量的值是相同的。
    > 开发中,常将一些常量声明是静态的。比如:Math类中的PI

    什么时候需要将方法声明为静态的?
    > 方法内操作的变量如果都是静态变量(而非实例变量)的话,则此方法建议声明为静态方法
    > 开发中,常常将工具类中的方法,声明为静态方法。比如:Arrays类、Math类

单例 (Singleton)设计模式

单例模式和实现思路(如果我们要让类在一个虚拟机...):

单例(Singleton)设计模式-饿汉式

单例(Singleton)设计模式-懒汉式

单例模式的优点

总结:

1.设计模式概述:
设计模式是在大量的`实践中总结`和`理论化`之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模式免去我们自己再思考和摸索.
就像是经典的棋谱,不同的棋局,我们用不同的棋谱。"套路"

经典的设计模式一共有23种。

2.何为单例模式(Singleton):
所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。

3.如何实现单例模式(掌握):
> 饿汉式

> 懒汉式

4.对比两种模式(特点、优缺点)
特点:
> 饿汉式:“立即加载”,随着类的加载,当前的唯一实例就创建了
> 懒汉式:"延迟加载",在需要使用的时候,进行创建。

优缺点:
> 饿汉式:(优点)写法简单,由于内存中较早加载,使用更方便、更快。是线程安全的。(缺点)内存中占用时间较长。
> 懒汉式: (缺点)线程不安全 (放到多线程章节时解决)(优点)在需要的时候进行创建,节省内存空间。

实例代码:

//饿汉式
public class BankTest {
    public static void main(String[] args) {
//        Bank bank1 = new Bank();
//        Bank bank2 = new Bank();
        Bank bank1 = Bank.getInstance();
        Bank bank2 = Bank.getInstance();
        System.out.println(bank1 == bank2); //true
    }
}
//饿汉式
class Bank {
    //1.类的构造器石私有化
    private Bank(){

    }
    //2.在类的内部创建当前类的实例
    //4.此属性也必须声明为static的
    private static Bank instance = new Bank();
    //3.使用getXXX()方法获取当前类的实例,必须声明为static的
    public static Bank getInstance(){
        return instance;
    }
}

//懒汉式
public class GirlFriendTest {
    public static void main(String[] args) {
        GirlFriend test1 = GirlFriend.getInstance();
        GirlFriend test2 = GirlFriend.getInstance();
        System.out.println(test1 == test2); //true
    }
}
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;
    }
}

理解main方法的语法

方式2:使用main()的形参进行传值。
代码:
public class MainDemo {
    public static void main(String[] args) {
        for (int i = 0; i < args.length; i++) {
            System.out.println("hello:" + args[i]);
        }
    }
}
命令行的方式传值:在执行命令后空格 写上实参
idea的传值方式

点击编辑配置:

执行结果:

总结:

main()方法的剖析
public static void main(string args[]){}

1.理解1: 看做是一个普通的静态方法
  理解2: 看做是程序的入口,格式是固定的。

2.与控制台交互
如何从键盘获取数据?
> 方式1:使用Scanner
> 方式2:使用main()的形参进行传值。
  命令行的方式传值  idea的传值方式

相关代码:

MainTest 
public class MainTest {
    public static void main(String[] args) { //程序的入口
        String[] arr = new String[]{"AA", "BB", "CC"};
        Main.main(arr);
    }
}
class Main{
    public static void main(String[] args) { //看做是普通的静态方法
        System.out.println("Main的main()的调用");
        for(int i = 0; i < args.length; i++){
            System.out.println(args[i]);
        }
        /**
         * Main的main()的调用
         * AA
         * BB
         * CC
         */
    }
}

类的成员之四:代码块

总结:

类的成员之四:代码块

回顾:类中可以声明的结构:属性、方法、构造器;代码块(或初始化块)、内部类

1.代码块(或初始化块)的作用:
(即初始化类或对象的成员变量)用来初始化类或对象的信息

2.代码块的修饰:
    只能使用static进行修饰。

3.代码块的分类:
    静态代码块:使用static修饰
    非静态代码块:没有使用static修饰

4.具体使用:
4.1 静态代码块:
    > 随着类的加载而执行
    > 由于类的加载只会执行一次,进而静态代码块的执行,也只会执行一次
    > 作用:用来初始化类的信息
    > 内部可以声明变量、调用属性或方法、编写输出语句等操作。
    > 静态代码块的执行要先于非静态代码块的执行
    > 如果声明有多个静态代码块,则按照声明的先后顺序执行
    > 静态代码块内部只能调用静态的结构(即静态的属性、方法),不能调用非静态的结构(即非静态的属性、方法)
4.2 非静态代码块:
    > 随着对象的创建而执行
    > 每创建当前类的一个实例,就会执行一次非静态代码块
    > 作用:用来初始化对象的信息
    > 内部可以声明变量、调用属性或方法、编写输出语句等操作。
    > 如果声明有多个非静态代码块,则按照声明的先后顺序执行
    >非静态代码块内部可以调用静态的结构(即静态的属性、方法),也可以调用非静态的结构(即非静态的属性、方法)

代码:

(1)声明User类
- 包含属性:userName(String类型),password(String类型),registrationTime(long类型),私有化

- 包含get/set方法,其中registrationTime没有set方法

- 包含无参构造,
    - 输出“新用户注册”,
    - registrationTime赋值为当前系统时间
    - userName就默认为当前系统时间值,
    - password默认为"123456"

- 包含有参构造(String userName,String password)
    - 输出“新用户注册”,
    - registrationTime赋值为当前系统时间,
    - username和password由参数赋值

- 包含public String getInfo()方法,返回:"用户名:xx,密码:xx,注册时间:xx"

(2)编写测试类,测试类main方法的代码
UserTest 
public class UserTest {
    public static void main(String[] args) {
        User u1 = new User();
        System.out.println(u1.getInfo());
        User u2 = new User("Tom","654321");
        System.out.println(u2.getInfo());
        System.out.println();
        User1 u3 = new User1();
        System.out.println(u3.getInfo());

    }
}

User1 
public class User1 {
    private String userName;
    private String password;
    private long registrationTime; //注册时间

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

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

    public long getRegistrationTime() {
        return registrationTime;
    }
    {
        System.out.println("新用户注册");
        registrationTime = System.currentTimeMillis(); //获取系统当前时间(距离1970-1-1 00:00:00的毫秒数)
    }
    //代码块的使用
    public User1(){
//        System.out.println("新用户注册");
//        registrationTime = System.currentTimeMillis(); //获取系统当前时间(距离1970-1-1 00:00:00的毫秒数)
        userName = System.currentTimeMillis() + "";
        password = "123456";
    }

    public User1(String userName, String password) {
//        System.out.println("新用户注册");
//        registrationTime = System.currentTimeMillis(); //获取系统当前时间(距离1970-1-1 00:00:00的毫秒数)
        this.userName = userName;
        this.password = password;
    }
    public String getInfo(){
        return "用户名:" + userName + ",密码:" + password + ",注册时间为:" + registrationTime;
    }
}

Field,属性赋值过程

总结:

可以给类的非静态的属性(即实例变量)赋值的位置有:
① 默认初始化
② 显式初始化 或 ⑤ 代码块中初始化
③ 构造器中初始化
******************************
④ 有了对象以后,通过"对象.属性"或"对象.方法"的方法进行赋值

2.执行的先后顺序:
① - ②/⑤ - ③ - ④

3.(超纲)关于字节码文件中的<init>的简单说明:(通过插件jclasslib bytecode viewer查看)
> <init>方法在字节码文件中可以看到。每个<init>方法都对应着一个类的构造器。(类中声明了几个构造器就会有几个<init>)
> 编写的代码中的构造器在编译以后就会以<init>方法的方式呈现
> <init>方法内部的代码包含了实例变量的显示赋值、代码块中的赋值和构造器中的代码。
> <init>方法用来初始化当前创建的对象的信息的。

4.给实例变量赋值的位置很多,开发中如何选?
> 显示赋值:比较适合于每个对象的属性值相同的场景
> 构造器中赋值:比较适合于每个对象的属性值不相同的场景

相关代码:

public class FieldTest {
    public static void main(String[] args) {
        Order o1 = new Order();
        System.out.println(o1.orderId); //1 ---> 2 ---> 3
    }
}
class Order {
    /**
     * 显式初始化 与 代码块中初始化 可以更换位置
     * 此时的执行结果是1
     * 反之执行结果是2
     * order类的加载有一个系的过程,在初始化之前orderId就已经被默认初始化了,并且默认为0,在后面才开始显示赋值或者代码块赋值
     */
//    {
//        orderId = 2;
//    }
//    int orderId = 1;
    int orderId = 1;
    {
        orderId = 2;
    }
    //构造器会以init的方式呈现的字节码中
    //字节码暴露了我们加载的顺序
    public Order(){
        super();
//        orderId = 3;
    }
    public Order(int orderId){
        this.orderId = orderId;
    }
    //对象调用eat方法之前,类中就已经存在了sleep和eat方法了,所以不会报错
    public void eat(){
        sleep();
    }
    public void sleep(){

    }
}

字节码文件:

 两个构造函数,两个init

面试题1:

/**
 * static A
 * static B
 * I'm A Class
 * HelloA
 * I'm B Class
 * HelloB
 */
class HelloA {
    public HelloA() {
        System.out.println("HelloA");
    }
    {
        System.out.println("I'm A Class");
    }
    static{
        System.out.println("static A");
    }
}
class HelloB extends HelloA {
    public HelloB() {
        System.out.println("HelloB");
    }
    {
        System.out.println("I'm B Class");
    }
    static {
        System.out.println("static B");
    }
}
public class Test01 {
    public static void main(String[] args) {
        new HelloB();
    }
}

面试题2:

public class Test02 {
    static int x, y,z;
    static {
        int x = 5;
        x--; //就近原则,操作的是新定义的x
    }
    static {
        x--;
    }
    public static void method(){
        y = z++ + ++z;
    }
    public static void main(String[] args) {
        System.out.println("x = " + x);
        z--; //-1
        method(); //-1 + 1 = 0 = y   z: 1
        System.out.println("result:" + (z + y + ++z));  //1 + 0 + 2 = 3
    }
}

面试题3:

/**
 * Base
 * sub:100
 * sub
 * base:70
 */
class Base {
    Base(){
        method(100);
    }
    {
        System.out.println("Base");
    }
    public void method(int i){
        System.out.println("base:" + i);
    }
}
class Sub extends Base {
    Sub(){
        super.method(70);
    }
    {
        System.out.println("sub");
    }
    public void method(int i){
        System.out.println("sub:" + i);
    }
}
public class Test03 {
    public static void main(String[] args) {
        Sub s = new Sub();
    }
}

关键字:final

总结:

final关键字的使用

1.final的理解:最终的

2.final可以用来修饰的结构:类、方法、变量

3.具体说明:

3.1 final修饰类:表示此类不能被继承。
    比如:String、stringBuffer、stringBuilder类
3.2 final修饰方法:表示此方法不能被重写
    比如:0bject类中的getClass()
3.3 final修饰变量:既可以修饰成员变量,也可以修饰局部变量。
    此时的"变量"其实就变成了"常量",意味着一旦赋值,就不可更改。
    3.3.1 final修饰成员变量:有哪些位置可以给成员变量赋值?
        > 显式赋值
        > 代码块中赋值
        > 构造器中赋值
    3.3.2 final修饰局部变量:一旦赋值就不能修改
    > 方法内声明的局部变量: 在调用局部变量前,一定需要赋值。而且一旦赋值,就不可更改
    > 方法的形参: 在调用此方法时,给形参进行赋值。而且一旦赋值,就不可更改

4.final与static搭配: 修饰成员变量时,此成员变量称为:全局常量。
比如:Math的PI

 相关代码:

public class FinalTest {
    public static void main(String[] args) {
        E e = new E();
        System.out.println(e.MIN_SCORE);
        //编译不通过
//        e.MIN_SCORE = 1;
        E e1 = new E(10);
//        e1.LEFT = 11; //不可更改
    }
}
class E {
    //成员变量
    final int MIN_SCORE = 0; //显式赋值
    final int MAX_SCORE;
    final int LEFT;
//    final int RIGHT; //不赋值会报错
    {
//        MIN_SCORE = 1;
        MAX_SCORE = 100; //代码块赋值
    }
    {
//        MAX_SCORE = 1; //编译不通过
    }
    public E(){
        LEFT = 2;
    }
    public E(int left){
        LEFT = left;
    }
    //报错
//    public void setRight(int right){
//        RIGHT = right;
//    }
}
class F {
    public void method(){
        final int num = 10;
//        num++;//编译报错
        System.out.println(num);
    }
    public void method(final int num){
//        num++; //编译报错
        System.out.println(num);
    }
}
final class A {

}
//报错,不能被继承
//class B extends A {
//
//}
//class subString extends String {}
class C{
    public final void method(){}
}
class D extends C{
    //不能被重写
//    public void method(){
//
//    }
}

面试题:

题目1:排错
public class Something {
    public int addOne(final int x){
        return ++x; //会报错,x已被赋值了
        //return x+1;
    }
}

题目2:排错
public class Something {
    public static void main(String[] args){
        Other o = new Other();
        new Something().addOne(o);
    }
    //这个地方final修饰的是o,如果o被重新赋值了的话就会报错
    //但是i是一个变量,他是用final修饰的
    public void addOne(final Other o){
        //o= new Other();
        o.i++;
    }
}

class Other {
    public int i:
}

抽象类与抽象方法

 选中这行按alt+enter键,选择实现方法(用于抽象子类重写父类的抽象方法)

弹出要实现的方法确定即可

案例:

Creature 
public abstract class Creature { //生物类
    public abstract void breath(); //呼吸
}

Person 
public abstract class Person extends Creature { //抽象类
    String name;
    int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public abstract void eat(); //抽象方法
    public abstract void sleep(); //抽象方法
}

Student 
public class Student extends Person {
    String school;

    public Student() {
    }

    public Student(String name, int age, String school) {
        super(name, age);
        this.school = school;
    }
    public void eat(){
        System.out.println("学生多吃有营养的食物");
    }
    public void sleep(){
        System.out.println("学生要保证充足的睡眠");
    }

    @Override
    public void breath() {
        System.out.println("学生应该多呼吸新鲜空气");
    }
}

Worker 
//public abstract class Worker extends Person{
//
//}
public abstract class Worker extends Person{

    @Override
    public void eat() {
        System.out.println("工人很辛苦,多吃");
    }
}

AbstractTest 
public class AbstractTest {
    public static void main(String[] args) {
        //编译不通过
//        Person p1 = new Person();
//        p1.eat();
        Student s1 = new Student();
        s1.eat();

        //抽象类不能实例化
//        Worker w1 = new Worker();
    }
}

AbstractTest1 
public class AbstractTest1 {
    //编译不通过
//    private abstract void method(){};
//    public static abstract void method(){};
}

抽象类应用

多态的应用:模板方法设计模式(TemplateMethod)

总结:

抽象类与抽象方法

1.案例引入
举例1:Geometric0bject-Circle-Rectangle

abstract class Geometric0bject{//几何图形
    //求面积(只能考虑提供方法的声明,而没有办法提供方法体。所以,此方法适合声明为抽象方法)
    //求周长(只能考虑提供方法的声明,而没有办法提供方法体。所以,此方法适合声明为抽象方法)
}

class Circle extends Geometric0bject {
    //求面积(必须重写(或实现)父类中的抽象方法)
    //求周长(必须重写(或实现)父类中的抽象方法)
}

举例2:Account-SavingAccount-CheckAcount
class Account{
    double balance;//余额
    //取钱 (声明为抽象方法)
    //存钱 (声明为抽象方法)
}

class SavingAccount extends Account{ //储蓄卡
    //取钱 (需要重写父类中的抽象方法)
    //存钱 (需要重写父类中的抽象方法)
}

class CheckAccount extends Account{ //信用卡
    //取钱 (需要重写父类中的抽象方法)
    //存钱 (需要重写父类中的抽象方法)
}

//......

2.abstract的概念:抽象的

3.abstract可以用来修饰:类、方法

4.具体的使用:

4.1 abstract修饰类:
    > 此类称为抽象类
    > 抽象类不能实例化。
    > 抽象类中是包含构造器的,因为子类对象实例化时,需要直接或间接的调用到父类的构造器。
    > 抽象类中可以没有抽象方法。反之,抽象方法所在的类,一定是抽象类,
        (因为需要确保这个方法不能被调用,而方法是需要通过对象来调用,这样干脆让类为抽象类,不能实例化)

4.2 abstract修饰方法
    > 此方法即为抽象方法
    > 抽象方法只有方法的声明,没有方法体。
    > 抽象方法其功能是确定的(通过方法的声明即可确定),只是不知道如何具体实现(体现为没有方法体)
    > 子类必须重写父类中的所有的抽象方法之后,方可实例化。否则,此子类仍然是一个抽象类

5.abstract不能使用的场景
5.1 abstract 不能修饰哪些结构?
属性、构造器、代码块等。

5.2 abstract 不能与哪些关键字共用? (自洽)
不能用abstract修饰私有方法、静态方法、final的方法、final的类
> 私有方法不能重写
> 避免静态方法使用类进行调用
> final的方法不能被重写
> final修饰的类不能有子类

练习:

编写工资系统,实现不同类型员工(多态)的按月发放工资。如果当月出现某个
Employee对象的生日,则将该雇员的工资增加100元。

实验说明:
(1)定义一个Employee类,该类包含:
private成员变量name,number,birthday,其中birthday 为MyDate类的对象;提供必要的构造器
abstract方法earnings();
toString()方法输出对象的name,number和birthday。

(2)MyDate类包含:
private成员变量year,month,day ;提供必要的构造器
toDateString()方法返回日期对应的字符串:xxxx年xx月xx日

(3)定义SalariedEmployee类继承Employee类,实现按月计算工资的员工处
理。该类包括:private成员变量monthlySalary;
提供必要的构造器;
实现父类的抽象方法earnings(),该方法返回monthlySalary值;toString()方法输
出员工类型信息及员工的name,number,birthday。比如:SalariedEmployee[name = '', number = '', birthday = '']

(4)参照SalariedEmployee类定义HourlyEmployee类,实现按小时计算工资的
员工处理。该类包括:
private成员变量wage和hour;
提供必要的构造器;
实现父类的抽象方法earnings(),该方法返回wage*hour值;
toString()方法输出员工类型信息及员工的name,number,birthday。比如:HourlyEmployee[name = '', number = '', birthday = '']

(5)定义PayrollSystem类,创建Employee变量数组并初始化,该数组存放各
类雇员对象的引用。利用循环结构遍历数组元素,输出各个对象的类
型,name,number,birthday,以及该对象生日。当键盘输入本月月份值时,如果本
月是某个Employee对象的生日,还要输出增加工资信息。
提示:
//定义People类型的数组People c1[]=new People[10];
//数组元素赋值
c1[0]=new People("John","0001",20);
c1[1]=new People("Bob","0002",19);
//若People有两个子类Student和Officer,则数组元素赋值时,可以使父类类型的数组元素指向子类。
c1[0]=new Student("John","0001",20,85.0);
c1[1]=new Officer("Bob","0002",19,90.5);
TemplateMethodTest 
public class TemplateMethodTest {
    public static void main(String[] args) {
        BankTemplateMethod btm = new DrawMonney();
        btm.process();
        BankTemplateMethod btm2 = new ManageMonney();
        btm2.process();
    }
}
abstract class BankTemplateMethod {
    //具体方法
    public void takeNumber(){
        System.out.println("排队取号");
    }
    public abstract void transact();
    public void evaluate(){
        System.out.println("反馈评分");
    }
    //模板方法,把基本操作组合到一起,子类一般不能重写
    public final void process(){
        this.takeNumber();
        this.transact(); //像个钩子,具体执行时,挂哪个类,就执行哪个子类的实现代码
        this.evaluate();
    }
}
class DrawMonney extends BankTemplateMethod {
    public void transact(){
        System.out.println("我要取款!!!");
    }
}
class ManageMonney extends BankTemplateMethod {
    public void transact(){
        System.out.println("我要理财!我这里有2000万美元!!");
    }
}

或练习
public class TemplateTest {
    public static void main(String[] args) {
        PrintPrimeNumber p = new PrintPrimeNumber();
        p.spendTime();
    }
}
abstract class Template {
    //计算某段代码的执行,需要花费的时间
    public void spendTime(){
        long start = System.currentTimeMillis();
        code();
        long end = System.currentTimeMillis();
        System.out.println("花费的时间为:" + (end - start));
    }
    public abstract void code();
}
class PrintPrimeNumber extends Template {
    public void code(){
        for(int i = 2; i <= 100000; i++){
            boolean isFlag = true;
            for(int j = 2; j <= Math.sqrt(i); j++){
                if(i % j == 0){
                    isFlag = false;
                    break;
                }
            }
            if(isFlag){
                System.out.println(i);
            }
        }
    }
}

接口(interface)

相关代码:

public class InterfaceTest {
    public static void main(String[] args) {
        System.out.println(Flyable.MIN_SPEED);
        System.out.println(Flyable.MAX_SPEED);
        //编译报错
//        Flyable.MAX_SPEED = 7800;
        Bullet b1 = new Bullet();
        b1.fly();
        b1.attack();
        //接口的多态性
        Flyable f1 = new Bullet();
        f1.fly(); //编译的时候是接口当中的方法,但是运行的时候是实现类当中的方法

    }
}
interface Flyable { //接口
    //全局常量
    public static final int MIN_SPEED = 0;
    // 可以省略public static final
    int MAX_SPEED = 7900;
    //方法可以省略public abstract声明
//    public abstract void fly();
    void fly();
}
interface Attackable { //接口
    public abstract void attack();
}
abstract class Plane implements Flyable,Attackable {

}
class Bullet implements Flyable {
    public void fly() {
        System.out.println("让子弹飞一会儿");
    }
    public void attack(){
        System.out.println("子弹可以击穿身体");
    }
}
//测试接口的继承关系
interface AA {
    void method1();
}
interface BB{
    void method2();
}
interface CC extends AA,BB{ //接口可以多继承
}
class DD implements CC {
    public void method1(){

    }
    public void method2(){

    }
}

练习题:

设备连接

/**
 * 设备连接成功...
 * 打印机开始工作
 * 数据传输的细节操作...
 * 打印机结束工作
 * 设备连接成功...
 * 照相机开始工作
 * 数据传输的细节操作...
 * 照相机结束工作
 * 设备连接成功...
 * U盘开始工作
 * 数据传输的细节操作...
 * U盘开始结束工作
 * 设备连接成功...
 * 扫描仪开始工作
 * 数据传输的细节操作...
 * 扫描仪结束工作
 */
public class USBTest {
    public static void main(String[] args) {
        //1.创建接口实现类的对象
        Computer computer = new Computer();
        Printer printer = new Printer();
        computer.transferDate(printer);
        //2.创建接口实现类的匿名对象
        computer.transferDate(new Camera());
        //3.创建接口匿名实现类的对象
        USB usb1 = new USB(){
            public void start(){
                System.out.println("U盘开始工作");
            }
            public void stop(){
                System.out.println("U盘开始结束工作");
            }
        };
        computer.transferDate(usb1);
        //4.创建接口匿名实现类的匿名对象
        computer.transferDate(new USB(){
            public void start(){
                System.out.println("扫描仪开始工作");
            }
            public void stop(){
                System.out.println("扫描仪结束工作");
            }
        });
    }
}
class Computer {
    public void transferDate(USB usb){
        System.out.println("设备连接成功...");
        usb.start();
        System.out.println("数据传输的细节操作...");
        usb.stop();
    }
}
class Camera implements USB {

    @Override
    public void start() {
        System.out.println("照相机开始工作");
    }

    @Override
    public void stop() {
        System.out.println("照相机结束工作");
    }
}
class Printer implements USB {

    @Override
    public void start() {
        System.out.println("打印机开始工作");
    }

    @Override
    public void stop() {
        System.out.println("打印机结束工作");
    }
}
interface USB {
    //声明常量
    //USB的长、宽、高...
    //方法
    public abstract void start();
    void stop();
}

练习2: 

1、声明接口Eatable,包含抽象方法public abstract void eat();
2、声明实现类中国人Chinese,重写抽象方法,打印用筷子吃饭
3、声明实现类美国人American,重写抽象方法,打印用刀叉吃饭
4、声明实现类印度人Indian,重写抽象方法,打印用手抓饭
5、声明测试类EatableTest,创建Eatable数组,存储各国人对象,并遍历数组,调用eat()方法
Chinese 
public class Chinese implements Eatable {
    public void eat() {
        System.out.println("中国人使用筷子吃饭");
    }
}
American 
public class American implements Eatable {

    @Override
    public void eat() {
        System.out.println("美国人使用刀叉吃饭");
    }
}
Indian 
public class Indian implements Eatable{
    @Override
    public void eat() {
        System.out.println("印度人使用手抓饭");
    }
}

public interface Eatable {
    void eat();
}

EatableTest 
public class EatableTest {
    public static void main(String[] args) {
        Eatable[] eatables = new Eatable[3];
        eatables[0] = new Chinese(); //多态性
        eatables[1] = new American();
        eatables[2] = new Indian();
        /**
         * 中国人使用筷子吃饭
         * 美国人使用刀叉吃饭
         * 印度人使用手抓饭
         */
        for (int i = 0; i < eatables.length; i++) {
            eatables[i].eat();
        }
    }
}

练习题3:

定义一个接口用来实现两个对象的比较。

interface CompareObject{
    //若返回值是0,代表相等;若为正数,代表当前对象大;负数代表当前对象小
    public int compareTo(Object o);
}
定义一个Circle类,声明radius属性,提供getter和setter方法

定义一个ComparableCircle类,继承Circle类并且实现CompareObject接口。
在ComparableCircle类中给出接口中方法compareTo的实现体,用来比较两个圆的半径大小。

定义一个测试类InterfaceTest,创建两个ComparableCircle对象,调用compareTo方法比较两个类的半径大小。

拓展:参照上述做法定义矩形类Rectangle和ComparableRectangle类,在ComparableRectangle类
中给出compareTo方法的实现,比较两个炬形的面积大小。
CompareObject 
public interface CompareObject {
    //若返回值是 0,代表相等,若为正数,代表当前对象大;负数代表当前对象小
    public int compareTo(Object o);
}

Circle 
public class Circle {
    private double radius; //半径

    public Circle() {
    }
    public Circle(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }

    @Override
    public String toString() {
        return "Circle{" +
                "radius=" + radius +
                '}';
    }
}

ComparableCircle 
public class ComparableCircle extends Circle implements CompareObject {
    public ComparableCircle() {
    }

    public ComparableCircle(double radius) {
        super(radius);
    }

    //根据对象半径的大小,比较对象的大小
    @Override
    public int compareTo(Object o) {
        if(this == o) {
            return 0;
        }
        if(o instanceof ComparableCircle) {
            ComparableCircle c = (ComparableCircle)o;
            // 错误的
//            return (int)(this.getRadius() - c.getRadius());
            //正确的写法1:
//            if(this.getRadius() > c.getRadius()) {
//                return 1;
//            }else if(this.getRadius() < c.getRadius()){
//                return -1;
//            }else {
//                return 0;
//            }
            //正确的写法2:
            return Double.compare(this.getRadius(), c.getRadius());
        }else {
            return 2; //如果输入的类型不匹配,则返回2
//            throw new RuntimeException("输入的类型不匹配");
        }
    }
}
InterfaceTest 
public class InterfaceTest {
    public static void main(String[] args) {
        ComparableCircle c1 = new ComparableCircle(2.3);
        ComparableCircle c2 = new ComparableCircle(5.3);
        int compareValue = c1.compareTo(c2);
        if(compareValue > 0){
            System.out.println("c1对象大");
        }else if(compareValue < 0){
            System.out.println("c2对象大");
        }else{
            System.out.println("c1和c2一样大");
        }
    }
}

接口的应用:代理模式(Proxy)

 总结:

接口的使用

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

2.定义接口的关键字:interface

3.接口内部结构的说明:
    > 可以声明:
        属性:必须使用public static final修饰
        方法:jdk8之前:声明抽象方法,修饰为public abstract
            jdk8:声明静态方法、默认方法
            jdk9:声明私有方法

    > 不可以声明: 构造器、代码块等

4.接口与类的关系:实现关系

5.格式: class A extends SuperA implements B,C{}
A相较于SuperA来讲,叫做子类
A相较于B,C来讲,叫做实现类。


6.满足此关系之后,说明:
> 类可以实现多个接口。
> 类针对于接口的多实现,一定程度上就弥补了类的单继承的局限性。
> 类必须将实现的接口中的所有的抽象方法都重写(或实现),方可实例化。否则,此实现类必须声明为抽象类。

7.接口与接口的关系: 继承关系,且可以多继承

8.接口的多态性: 接口名 变量名 = new 实现类对象;
             // 父类 变量名 = new 子类对象; 类的多态性
9.面试题:区分抽象类和接口
> 共性:都可以声明抽象方法
    都不能实例化
> 不同:① 抽象类一定有构造器。接口没有构造器
      ② 类与类之间继承关系,类与接口之间是实现关系,接口与接口之间是多继承关系

相关代码 :

CompareA 
public interface CompareA {
    //属性:声明为public static final
    //方法:jdk8之前,只能声明抽象方法
    //方法:jdk8中:静态方法
    public static void method1(){
        System.out.println("CompareA:北京");
    }
    //方法:jdk8中:默认方法
//    public void method3(); //这种写法是抽象方法,不是抽象方法就需要抽象体
    public default void method2(){
        System.out.println("CompareA:上海");
    };
    public default void method3(){
        System.out.println("CompareA:广州");
    };
    public default void method4(){
        System.out.println("CompareA:深圳");
    };
    //jdk9新特性:定义私有方法
    private void method5(){
        System.out.println("我是接口中定义的私有方法");
    }
}
CompareB 
public interface CompareB {
    public default void method3(){
        System.out.println("CompareB: 广州");
    }
}
SuperClass 
public class SuperClass {
    public void method4() {
        System.out.println("SuperClass:深圳");
    }
}
SubClassTest 
public class SubClassTest {
    public static void main(String[] args) {
        //知识点1:接口中声明的静态方法只能被接口来调用,不能使用期实现类进行调用
        CompareA.method1();
//        SubClass.method1(); //编译不通过
        //默认方法涉及到造对象,重写之后调用的是重写之后的方法
        //知识点2:接口中声明的默认方法可以被类继承,实现类在没有重写此方法的情况下,默认调用接口中声明的
        //默认方法,如果实现类重写了此方法,则调用的是自己重写的方法
        SubClass s1 = new SubClass();
        s1.method2();
        //知识点3:类实现了两个接口,而两个接口中定义了同名同参数的默认方法,则实现类在没有重写此两个接口
        //默认方法的情况下,或报错,--->接口冲突
        //要求:此时实现类必须要重写接口中定义的同名同参数的方法
        s1.method3();
        //知识点4:子类(或实现类)继承了父类并实现了接口,父类和接口中声明了同名同参数的方法,(其中,接口中的方法
        //是默认方法)。默认情况下,子类(或实现类)在没有重写此方法的情况下,调用的是父类中的方法。---> 类优先原则
        /**
         * CompareA:北京
         * SubClass:上海
         * SubClass:广州
         * SuperClass:深圳 ---> SubClass:深圳(子类重写之后)
         */
        s1.method4();
    }
}
SubClass 
public class SubClass extends SuperClass implements CompareA, CompareB {
    @Override
    public void method2() {
        System.out.println("SubClass:上海");
    }

    @Override
    public void method3() {
        System.out.println("SubClass:广州");
    }
    public void method4() {
        System.out.println("SubClass:深圳");
    }
    public void method(){
        //知识点5:如何在子类(或实现类)中调用父类或接口中重写的方法
        method4(); //调用自己类中的方法
        super.method4();
        method3(); //调用自己类中的方法
//        CompareA.method1(); //静态方法可以这样调用,不是静态的方法按照下面的方式调用
        CompareA.super.method3(); //调用接口CompareA中的默认方法
        CompareB.super.method3(); //调用接口CompareB中的默认方法
    }
}

类的成员之五:内部类

内部类生成的文件通过 $内部类名 来表示

代码示例:

public class OuterClassTest {
    public static void main(String[] args) {
        //1.创建Person的静态的成员内部类的实例
        Person.Dog dog = new Person.Dog();
        dog.eat();
        //2.创建Person的非静态的成员内部类的实例
//        Person.Bird bird = new Person.Bird(); //报错
         Person p1 = new Person();
         Person.Bird bird = p1.new Bird(); //正确的
         bird.eat();
         bird.show("黄鹂");
         bird.show1();
    }
}
class Person { //外部类
    String name = "Tom";
    int age = 1;
    //静态的成员内部类
    static class Dog{
        public void eat() {
            System.out.println("狗吃骨头");
        }
    }
    //非静态的成员内部类
    class Bird{
        String name = "啄木鸟";
        public void eat(){
            System.out.println("鸟吃虫子");
        }
        public void show(String name){
            System.out.println("age = " + age); //age = 1 省略了Person.this
            System.out.println("name = " + name); //name = 黄鹂
            System.out.println("name = " + this.name); //name = 啄木鸟
            System.out.println("name = " + Person.this.name); //name = Tom
        }
        public void show1(){
            eat(); //鸟吃虫子
            this.eat(); //鸟吃虫子
            Person.this.eat(); //人吃饭
        }
    }
    public void eat(){
        System.out.println("人吃饭");
    }
    public void method(){
        //局部内部类
        class innerClass1{

        }
    }
    public Person(){
        //局部内部类
        class innerClass1{

        }
    }
    {
        //局部内部类
        class innerClass1{

        }
    }
}

代码示例2:

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;
        //方式1:提供了接口的实现类的匿名对象
//        class MyComparable implements Comparable{
//
//            @Override
//            public int compareTo(Object o) {
//                return 0;
//            }
//        }
//        return new MyComparable();
        //方式2:提供了接口的匿名实现类的对象
        //后面的大括号表示实现类
//        Comparable c = new Comparable() {
//            @Override
//            public int compareTo(Object o) {
//                return 0;
//            }
//        };
//        return c;
        //方式3:提供了接口的匿名实现类的匿名对象
        return new Comparable(){

            @Override
            public int compareTo(Object o) {
                return 0;
            }
        };
    }
}

代码示例3:

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() {
            @Override
            public void method1() {
                System.out.println("继承于抽象类的子类调用的方法");
            }
        };
        b.method1();
        System.out.println(b.getClass()); //class com.atguigu09.inner.OuterClassTest2$3
        System.out.println(b.getClass().getSuperclass()); //class com.atguigu09.inner.B

        //举例5:
        new B(){

            @Override
            public void method1() {
                System.out.println("继承于抽象类的子类调用的方法1");
            }
        }.method1();
        //举例6:
        C c = new C();
        c.method2();
        //举例7:提供了一个继承于C的匿名子类的对象
//        C c1 = new C(){};
        C c1 = new C(){
            public void method2() {
                System.out.println("SubC");
            }
        };
        c1.method2();
//        System.out.println(c.getClass());//class com.atguigu09.inner.C
//        System.out.println(c1.getClass().getSuperclass());//class com.atguigu09.inner.C
    }
}
interface A{
    public void method();
}
class SubA implements A{
    public void method(){
        System.out.println("SubA");
    }
}
abstract class B{
    public abstract void method1();
}
class SubB extends B{
    public void method1(){
        System.out.println("SubB");
    }
}
class C{
    public void method2(){
        System.out.println("C");
    }
}

练习1:

编写一个匿名内部类,它继承Object,并在匿名内部类中,声明一个方法public void test()打印尚硅谷。
请编写代码调用这个方法。
public class ObjectTest {
    public static void main(String[] args) {
//        SubObject sub1 = new SubObject();
//        sub1.test();
        //提供一个继承于Object的匿名子类的匿名对象
        new Object(){
            public void test(){
                System.out.println("尚硅谷");
            }
        }.test();
    }
}
class SubObject extends Object{
    public void test(){
        System.out.println("尚硅谷");
    }
}

native关键字的理解: 

枚举类enum

单例模式当中有饿汉式与懒汉式

总结:

枚举类的使用
1.枚举类的理解:枚举类型本质上也是一种类,只不过是这个类的对象是有限的、固定的几个,不能让用户随意创建。
2.举例:
- 星期:Monday(星期一)......Sunday(星期天)
- 性别:Man(男)、Woman(女)
- 月份:January(1月)......December(12月)
- 季节:Spring(春节)......Winter(冬天)
- 三原色:red(红色)、green(绿色)、blue(蓝色)
- 支付方式:Cash(现金)、WechatPay(微信)、Alipay(支付宝)、BankCard(银行卡)、Creditcard(信用卡)
- 就职状态:Busy(忙碌)、Free(空闲)、Vocation(休假)、Dimission(离职)
- 订单状态:Nonpayment(未付款)、Paid(已付款)、Fulfilled(已配货)、Delivered(已发货)、checked(已确认收货)、Return(退货)、Exchange(换货)、Cancel(取消)
- 线程状态:创建、就绪、运行、阻塞、死亡

3.开发中的建议:
> 开发中,如果针对于某个类,其实例是确定个数的,则推荐将此类声明为枚举类
> 如果枚举类的实例只有一个,则可以看做是单例的实现方式。

4.JDK5.0 之前如何自定义枚举类(了解)
见代码
5.JDK5.0中使用enum定义枚举类
见代码
6.Enum中的常用方法:
6.1 使用enum关键字定义的枚举类,默认其父类是java.lang.Enum类
    使用enum关键字定义的枚举类,不要再显示的定义其父类。否则报错
6.2 熟悉Enum类中常用的方法
    string toString():默认返回的是常量名(对象名),可以继续手动重写该方法!
    (关注)static 枚举类型[] valves():返回枚举类型的对象数组。该方法可以很方便地遍历所有的枚举值,是一个静态方法
    (关注)static 枚举类型 value0f(String name):可以把一个字符串转为对应的枚举类对象。要求字符串必须是枚举类对象的"名字"。如不是,会有运行时异常:IllegalArgumentException。
    String name():得到当前枚举常量的名称。建议优先使用toString()。
    int ordinal():返回当前枚举常量的次序号,默认从0开始
7.枚举类实现接口的操作
    情况1:枚举类实现接口,在枚举类中重写接口中的抽象方法。当通过不同的枚举类对象调用此方法时,执行的是同一个方法。
    情况2:让枚举类的每一个对象重写接口中的抽象方法。当通过不同的枚举类对象调用此方法时,执行的是不同的实现的方法。

相关代码1:

public class SeasonTest {
    public static void main(String[] args) {
//        Season.AUTUMN = null; //报错
        System.out.println(Season.SPRING);
        System.out.println(Season.SUMMER.getSeasonName());
        System.out.println(Season.SUMMER.getSeasonDesc());
    }
}
//jdk5.0之前定义的枚举方式
class Season{
    //2.声明当前类的对象的实例变量,使用private 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.创建当前类的实例,使用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 + '\'' +
                '}';
    }
}

相关代码2:

public class SeasonTest1 {
    public static void main(String[] args) {
//        System.out.println(Season1.SPRING.getClass()); //class com.atguigu10._enum.Season1
//        System.out.println(Season1.SPRING.getClass().getSuperclass()); //class java.lang.Enum
//        System.out.println(Season1.SPRING.getClass().getSuperclass().getSuperclass()); //class java.lang.Object
        //测试方法
        //1.toString()
        System.out.println(Season1.SPRING); //SPRING(toString()重写之前)
        //2.name()
        System.out.println(Season1.SPRING.name()); //SPRING
        //3.values()
        Season1[] values = Season1.values();
        /**
         * Season1{seasonName='春天', seasonDesc='春暖花开'}
         * Season1{seasonName='夏天', seasonDesc='夏日炎炎'}
         * Season1{seasonName='秋天', seasonDesc='秋高气爽'}
         * Season1{seasonName='冬天', seasonDesc='白雪皑皑'}
         */
        for(int i=0; i<values.length; i++){
            System.out.println(values[i]);
        }
        //4.valueOf(String objName):再返回当前枚举类中名称为objName的枚举对象
        //如果枚举类不存在objName名称的对象,则报错
        String objName = "WINTER";
//        objName = "WINTER1"; //报错IllegalArgumentException
        Season1 season1 = Season1.valueOf(objName);
        System.out.println(season1);
        //5.ordinal()
        System.out.println(Season1.AUTUMN.ordinal()); //2
        //通过枚举类的对象调用重写后的接口中的方法
        Season1.AUTUMN.show();
    }
}
interface Info{
    void show();
}
//jdk5.0中使用enum关键字定义枚举类
enum Season1 implements Info{
    //1.必须在枚举类的开头声明多个对象,对象之间使用,隔开
    SPRING("春天", "春暖花开"),
    SUMMER("夏天", "夏日炎炎"),
    AUTUMN("秋天", "秋高气爽"),
    WINTER("冬天", "白雪皑皑");

    //2.声明当前类的对象的实例变量,使用private 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;
    }


    @Override
    public String toString() {
        return "Season1{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
    @Override
    public void show() {
        System.out.println("这是一个季节");
    }
}


改进2
public class SeasonTest2 {
    public static void main(String[] args) {
        Season2[] values = Season2.values();
        for(int i = 0; i < values.length; i++){
//            System.out.println(values[i]);
            values[i].show();
        }
    }
}
interface Info1{
    void show();
}
//jdk5.0中使用enum关键字定义枚举类
enum Season2 implements Info1{
    //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.声明当前类的对象的实例变量,使用private 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 "Season1{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}

就职状态代码:

Employee 
public class Employee {
    private String name;
    private int age;
    private Status status;

    public Employee() {
    }

    public Employee(String name, int age, Status status) {
        this.name = name;
        this.age = age;
        this.status = status;
    }

    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;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", status=" + status +
                '}';
    }
}
枚举:
public enum Status {
    BUSY,FREE,VOCATION,DIMISSION;
}
EmployeeTest 
public class EmployeeTest {
    public static void main(String[] args) {
        Employee e1 = new Employee("Tom", 21, Status.BUSY);
        System.out.println(e1); //Employee{name='Tom', age=21, status=BUSY}
    }
}
案例:使用枚举类实现单例模式
public class BnakTest1 {
    public static void main(String[] args) {
//        Bank1.instance = null; //final可以用但不能修改
        System.out.println(GirlFriend.XIAL_LI); //XIAL_LI
    }
}
//jdk5.0之前的使用枚举类定义单例模式
class Bank1 {
    //饿汉式
//    private Bank1(){}
//    private static Bank1 instance = new Bank1();
//    public static Bank1 getInstance(){
//        return instance;
//    }
    //枚举类没有通过方法调用,而是直接通过类来调用
    private Bank1(){}
    private static final Bank1 instance = new Bank1();
}
//jdk5.0使用enum关键字定义枚举类的方式定义单例模式
enum Bank2{
    CPB;
}
enum GirlFriend{
//    public static final GirlFriend XIAL_LI = new GirlFriend(20); //之前写法
    XIAL_LI(20);
    private final int age;
    private GirlFriend(int age){
        this.age = age;
    }
}

案例: 

案例拓展:颜色枚举类(使用enum声明)
(1)声明颜色枚举类Color:
- 声明final修饰的int类型的属性red,green,blue
- 声明final修饰的String类型的属性description
- 声明有参构造器Color(int red,int green,int blue,String description)
- 创建7个常量对象:红、橙、黄、绿、青、蓝、紫,
- 重写toString方法,例如:RED(255,0,0)->红色
(2)在测试类中,使用枚举类,获取绿色对象,并打印对象。
提示:
- 7个常量对象的RGB值如下:
红:(255,0,0)
橙:(255,128,0)
黄:(255,255,0)
绿:(0,255,0)
青:(0,255,255)
蓝:(0,0,255)
紫:(128,0,255)

7个常量对象名如下
RED, ORANGE,YELLOW, GREEN,CYAN, BLUE,PURPLE
public class ColorTest {
    public static void main(String[] args) {
        System.out.println(Color.BLUE);
    }
}
enum Color {
    RED(255,0,0,"红色"),
    ORANGE(255,128,0,"橙色"),
    YELLOW(255,255,0,"黄色"),
    GREEN(0,255,0,"绿色"),
    CYAN(0,255,255,"青色"),
    BLUE(0,0,255,"蓝色"),
    PURPLE(128,0,255,"紫色");
    private final int red;
    private final int green;
    private final int blue;
    private final String description; //颜色的描述
    Color(int red, int green, int blue, String description) {
        this.red = red;
        this.green = green;
        this.blue = blue;
        this.description = description;
    }

    public int getRed() {
        return red;
    }

    public int getGreen() {
        return green;
    }

    public int getBlue() {
        return blue;
    }

    public String getDescription() {
        return description;
    }

    @Override
    public String toString() {
//        return name()+ "(" + red + "," + green + "," + blue + ")" + "--->" + description;
        return super.toString()+ "(" + red + "," + green + "," + blue + ")" + "--->" + description;
    }
}

annotation注解的使用

`@SuppressWarnings`:抑制编译器警告

移动到元素上,选择更多操作

结果如下:  @SuppressWarnings("unused") int num = 10;

JUnit单元测试

怎么添加单元测试包,通过+号选择库(library)

务必选择编译

就可以为当前模块(module)添加单元测试(junit)

也可以通过选中当前@Test这个测试类,按住alt+enter回车键,在有网的情况下下载包

默认情况下,单元测试方法中使用Scanner失效。如何解决?

在单元测试里面如果没有做什么配置,在这个地方输入什么都无法显示

如果不想是只读的,输入的数值可以显示出来,在help里面选择编辑自定义虚拟机选项

在这个文件中将这一句话加上:-Deditable.java.test.console=true

之后在文件地方选择使缓存失效

点击重启,或者直接关闭idea,重新打开也可

此时再输入数值就可以正常显示了

结果显示:

如何将将单元测试设置成一个模板?

使用模板,在光标出输入需要输入的值

总结和相关代码:

JUnit单元测试的使用
1.需要导入的jar包:
junit-4.12.jar
hamcrest-core-1.3.jar
2.导入步骤
见课件
3.创建单元测试类,进行测试
见代码
4.(重点关注)要想能正确的编写单元测试方法,需要满足:
- 所在的类必须是public的,非抽象的,包含唯一的无参构造器。
- @Test标记的方法本身必须是public,非抽象的,非静态的,void无返回值,()无参数的。
5.默认情况下,单元测试方法中使用Scanner失效。如何解决?

6.大家可以将单元测试设置成一个模板?
public class JunitTest { //单元测试类
    public static void main(String[] args) {
        //静态方法调用非静态方法需要进行测试
        JunitTest test = new JunitTest();
        System.out.println(test.number);
        test.method();
    }
    int number = 10;
    @Test
    public void test1() { //单元测试方法
        System.out.println("Hello");
    }
    @Test
    public void test2() {
        System.out.println("Hello1");
        System.out.println("number = " + number);
        method();
        int num = showInfo("China");
        System.out.println(num);
    }
    public void method() {
        System.out.println("method()......");
    }
    public int showInfo(String info){
        System.out.println(info);
        return 10;
    }
    @Test
    public void test3() {
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入一个数值");
        int num = sc.nextInt();
        System.out.println(num);
        for(int i = 1; i <= num; i++){
            System.out.println(i);
        }
    }
    @Test
    public void test4(){
        System.out.println("Hello4");
    }
    @Test
    public void test5(){
        System.out.println("Hello5");
    }
}

包装类(Wrapper)的使用

基本类型、包装类与String类间的转换

字节码文件可以体现出自动装箱与自动拆箱的过程

包装类缓存对象

面试题1:

public class InterviewTest1 {
    public static void main(String[] args) {
        Integer i = new Integer(1);
        Integer j = new Integer(1);
        System.out.println(i == j); // false
        //底层都会调用Integer的valueOf()
        //这个地方取得值是里面已经new好的Integer数组里面的对象,cache数组中每一个位置都是一个new Integer()对象,
        //所以他们的地址值都是相同的,都是取的cache数组中的第129位
        Integer m = 1; //自动装箱
        Integer n = 1;
        System.out.println(m == n); //true
        //根据valueOf的源码可知,这个地方的128不在[-128,127]范围内,所以是new Integer(i)的一个对象出来
        Integer x = 128;
        Integer y = 128;
        System.out.println(x == y); //false
    }
}

cache数组长度是256,循环,cache数组[第一位是-128,第二位是-127.....一直到127]为止

用自动装箱的方式,在这个范围内用==判断的全都是true,出了这个范围是false

面试题2:

public class InterviewTest2 {
    public static void main(String[] args) {
        //题目1:
        int i = 10;
        double d = 10.2;
        System.out.println(i == d); //false
        //题目2:
        Integer i1 = 10;
        Double d1 = 10.2;
//        System.out.println(i1 == d1); //报错,==可以比较引用类型的地址,但是需要时同一类型
        //题目3:会进行拆箱,m就会转成int类型的,装箱会成为不同引用类型,会报错
        Integer m = 1000; //1000先装箱,比较时拆箱
        double n = 1000;
        System.out.println(m == n); //true
        //题目4:
        Integer x = 1000;
        int y = 1000;
        System.out.println(x == y); // true
    }
}

int(i)类型转换成(to)成double类型(d)  i2d

面试题3:

public class InterviewTest3 {
    public static void main(String[] args) {
        //这个地方的比较有一个类型兼容的问题,所以输出结果是1.0
        Object o1 = true ? new Integer(1) : new Double(2.0);
        System.out.println(o1); //1.0
        Object o2;
        if(true)
            o2 = new Integer(1);
        else
            o2 = new Double(2.0);
        System.out.println(o2); //1
    }
}

总结:

包装类的使用
1.为什么要使用包装类?
为了使得基本数据类型的变量具备引用数据类型变量的相关特征(比如:封装性、继承性、多态性),我们给各个基本数据
类型的变量都提供了对应的包装类。
2.(掌握)基本数据类型对应的包装类类型
    byte -> Byte
    short -> Short
    int -> Integer
    long -> Long
    float -> Float
    double ->Double

    char -> Character
    boolean -> Boolean
3.掌握基本数据类型 与 包装类之间的转换。
    3.1 为什么需要转换
        > 一方面,在有些场景下,需要使用基本数据类型对应的包装类的对象。此时就需要将基本数据类型的变量转换为
            包装类的对象。比如:ArrayList的add(Object obj);Object类的equals(Object obj)
        > 对于包装类来讲,既然我们使用的是对象,那么对象是不能进行+ - * /等运算的。为了能够进行这些运算,就
            需要将包装类的对象转换为基本数据类型的变量。

    3.2 如何转换:
        (装箱)基本数据类型 ---> 包装类: ① 使用包装类的构造器 ② (建议)调用包装类的valueOf(xxxxx)
        (拆箱)包装类 ---> 基本数据类型: 调用包装类的xxxValue()
    注意:原来使用基本数据类型变量的位置,改成包装类以后,对于成员变量来说,其默认值变化了!

    jdk5.0新特性:自动装箱、自动拆箱。

4.String 与 基本数据类型、包装类之间的转换。
    基本数据类型、包装类---> String类型: ① String类型:调用String的重载的静态方法value0f(xxxxx); ② 基本数据类型的变量 + ""
    String类型 ---> 基本数据类型、包装类:调用包装类的静态方法:parseXxx()

相关代码:代码练习

public class WrapperTest {

    /**
     * 基本数据类型 ---> 包装类: ① 使用包装类的构造器 ② (建议)调用包装类的value0f(xxx xx)
     * 包装类 ---> 基本数据类型: 调用包装类的xxxValue()
     * jdk5.0新特性:自动装箱、自动拆箱。
     */
    @Test
    public void test4(){
        //自动装箱: 基本数据类型--->包装类
        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; //自动拆箱
    }
    @Test
    public void test3(){
        Account account = new Account();
        System.out.println(account.isFlag1); //false
        System.out.println(account.isFlag2); //null
        System.out.println(account.balance1); //0.0
        System.out.println(account.balance2); //null
    }
    @Test
    public void test2(){
        Integer ii1 = new Integer(10);
        int i1 = ii1.intValue();
        i1 = i1 + 1;
        Float ff1 = new Float(12.3F);
        float f1 = ff1.floatValue();
        Boolean bb1 = Boolean.valueOf(true);
        Boolean b1 = bb1.booleanValue();
    }
    @Test
    //基本数据类型 ---> 包装类: ① 使用包装类的构造器 ② (建议)调用包装类的value0f(xxx xx)
    public void test1(){
        int i1 = 10;
        Integer ii1 = new Integer(i1);
        System.out.println(ii1.toString()); //10
        float f1 = 12.3F;
        f1 = 32.2f;
        Float ff1 = new Float(f1);
        System.out.println(ff1.toString()); //32.2

        String s1 = "32.1";
        Float ff2 = new Float(s1);

//        s1 = "abc";
//        Float ff3 = new Float(s1); //报异常:NumberFormatException

        boolean b1 = true;
        Boolean bb1 = new Boolean(b1);
        System.out.println(bb1);//true

        //Boolean这块只要长的跟true不一样就是false了
        String s2 = "false";
        s2 = "False123";
        s2 = "TrUe"; //忽略大小写
        Boolean bb2 = new Boolean(s2);
        System.out.println(bb2); //false --> true

        //推荐使用
        int i2 = 10;
        Integer ii2 = Integer.valueOf(i2);
        Boolean b2 = Boolean.valueOf(true);
        Float f2 = Float.valueOf(12.3F);


    }
}
class Account{
    boolean isFlag1;
    Boolean isFlag2; //null 包装类
    double balance1; //0.0
    Double balance2; //null 包装类 0.0可以理解成这个对象被初始化了
}

相关代码2:

public class WrapperTest1 {
    /**
     * 基本数据类型、包装类---> ① String类型:调用String的重载的静态方法value0f(xxxxx); ② 基本数据类型的变量 + ""
     * String类型 ---> 基本数据类型、包装类:调用包装类的静态方法:parseXxx()
     */
    @Test
    public void test2(){
        String s1 = "123";
        int i1 = Integer.parseInt(s1);
        System.out.println(i1 + 10);
        String s2 = "true";
        boolean b1 = Boolean.parseBoolean(s2);
        //特别的
//        String s3 = "123a";
//        int i2 = Integer.parseInt(s3); //报错NumberFormatException
    }
    @Test
    public void test1(){
        //方式1:① String类型:调用String的重载的静态方法value0f(xxxxx); ② 基本数据类型的变量 + ""
        int i1 = 10;
        String str1 = String.valueOf(i1);
        System.out.println(str1); //"10"
        boolean b1 = true;
        Boolean b2 = b1;
        String str2 = String.valueOf(b1);
        String str3 = String.valueOf(b2);
        //方式2:基本数据类型的变量 + ""
        String str4 = i1 + "";
        String str5 = b1 + "";
    }
}

练习题:

利用Vector代替数组处理:从键盘读入学生成绩(以负数代表输入结束),找出最高分,并输出学生成绩等级。
提示:数组一旦创建,长度就固定不变,所以在创建数组前就需要知道它的长度。而向量类java.util.Vector可以根据需要动
1、创建Vector对象:Vector v=new Vector();
2、给向量添加元素:v.addElement(Object obj);//obj必须是对象
3、取出向量中的元素:Object obj=v.elementAt(0);
    注意第一个元素的下标是0,返回值是0bject类型的。
4、计算向量的长度:v.size();
5、若与最高分相差10分内:A等;20分内:B等;30分内:C等;其它:D等
package com.atguigu12.wrapper.exer;

import java.util.Scanner;
import java.util.Vector;

/**
 * ClassName: ScoreTest
 * Package: com.atguigu12.wrapper.exer
 * Description:
 *
 * @Author: shkstart
 * @Create 2025-03-25 23:46
 * @Version: 1.0
 */
public class ScoreTest {
    public static void main(String[] args) {
        //1.创建Vector对象:Vector v= new Vector();
        Vector v= new Vector();
        Scanner scanner = new Scanner(System.in);
        int maxScore = 0; //记录最高分
        //2.从键盘中获取学生成绩,存放到v中(以负数代表输入结果)
        while(true){
            System.out.print("请输入学生成绩(以负数代表输入结束):");
            int intScore =  scanner.nextInt();
            if(intScore < 0){
                break;
            }
//            //装箱:int ---> Integer对象
//            Integer score = Integer.valueOf(intScore);
//            //添加学生成绩到容器v中
//            v.addElement(score);

            //jdk5.0之后,自动装箱
            v.addElement(intScore);
            //3.获取学生成绩的最大值
            if(maxScore < intScore){
                maxScore = intScore;
            }
        }
        System.out.println("最高分:" + maxScore);
        //4.依次获取v中的每个学生成绩,与最高分进行比较,获取学生等级,进行输出
        for(int i = 0; i < v.size(); i++){
            Object objScore = v.elementAt(i);
            //方式1:
//            Integer integerScore = (Integer)objScore;
//            //拆箱
//            int score = integerScore.intValue();
            //方式2:自动拆箱
            int score = (Integer)objScore;
            char grade = ' ';
            if(maxScore - score <= 10){
                grade = 'A';
            }else if(maxScore - score <= 20){
                grade = 'B';
            }else if(maxScore - score <= 30){
                grade = 'C';
            }else {
                grade = 'D';
            }
            System.out.println("student " + i + " score: " + score + " grade: " + grade);
        }
        scanner.close();
    }
}

ctrl+fn+f12或ctrl+f12在当前文件进行搜索,搜索内容可以直接输入

IDEA断点调试

Person p1 = new Person(3);
System.out.println(p1.toString());  

toString()没有重写之前打印的是地址,对于引用数据类型来说,重写之后,打印的是重写之后的方法

总结:

IDEA中调试程序
1.为什么需要Debug?
编好的程序在执行过程中如果出现错误,该如何查找或定位错误呢?简单的代码直接就可以看出来,
但如果代码比较复杂,就需要借助程序调试工具(Debug)来查找错误了。
2. Debug的步骤
    1、添加断点
    2、启动调试
    3、单步执行
    4、观察变量和执行流程,找到并解决问题
Description:演示1:行断点,测试debug各个常见操作按钮
Description: 演示2: 方法断点
Description:演示3:字段断点
Description:演不4:条件断点

Description:演示7:强制结束

复习:

//底层都会调用Integer的valueOf()
//这个地方取得值是里面已经new好的Integer数组里面的对象,cache数组中每一个位置都是一个new Integer()对象,
//所以他们的地址值都是相同的,都是取的cache数组中的第129位
//享元设计模式
Integer m = 1; //自动装箱
Integer n = 1;
System.out.println(m == n); //true

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2322624.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++三大特性之继承

1.继承的概念及定义 回忆封装 C Stack类设计和C设计Stack对比。封装更好&#xff1a;访问限定符类的数据和方法放在一起 -> 避免底层接口的暴露&#xff0c;数据更加的安全&#xff0c;程序的耦合性更高迭代器的设计&#xff0c;封装了容器底层结构&#xff0c;在不暴露底层…

解决Vmware 运行虚拟机Ubuntu22.04卡顿、终端打字延迟问题

亲测可用 打开虚拟机设置&#xff0c;关闭加速3D图形 &#xff08;应该是显卡驱动的问题&#xff0c;不知道那个版本的驱动不会出现这个问题&#xff0c;所以干脆把加速关了&#xff09;

ctfshow做题笔记—栈溢出—pwn73、pwn74

目录 一、pwn73(愉快的尝试一下一把梭吧&#xff01;) 二、pwn74(噢&#xff1f;好像到现在为止还没有了解到one_gadget?) 前言&#xff1a; 抽空闲时间继续学习&#xff0c;记录了两道题&#xff0c;pwn74卡了几天哈哈。 一、pwn73(愉快的尝试一下一把梭吧&#xff01;) …

026-zstd

zstd 以下为Zstandard&#xff08;zstd&#xff09;压缩算法从原理到代码实现的技术调研报告&#xff0c;结合流程图、结构图及完整C代码实现&#xff1a; 一、核心原理与技术架构 1.1 算法原理 Zstd基于LZ77衍生算法与熵编码&#xff08;FSE/Huffman&#xff09;的混合架构&…

AF3 quat_to_rot函数解读

AlphaFold3 rigid_utils 模块的 quat_to_rot 函数的功能是把四元数转换为旋转矩阵,函数利用预定义的四元数到旋转矩阵的转换表 _QTR_MAT 来简化计算。 理解四元数到旋转矩阵的转换 源代码: _quat_elements = ["a", "b", "c", "d"]…

Elasticsearch 的搜索功能

Elasticsearch 的搜索功能 建议阅读顺序&#xff1a; Elasticsearch 入门Elasticsearch 搜索&#xff08;本文&#xff09; 1. 介绍 使用 Elasticsearch 最终目的是为了实现搜索功能&#xff0c;现在先将文档添加到索引中&#xff0c;接下来完成搜索的方法。 查询的分类&…

CSS+JS 堆叠图片动态交互切换

结合DeepSeek提供的代码&#xff0c;终于实现了堆叠两张图片动态循环切换&#xff0c;以下是代码&#xff1a; 通过绝对定位放了两张图片 <div class"col-lg-5" style"z-index: 40; position: relative;"><img src"images/banner_1.png&quo…

内存检查之Valgrind工具

内存检查之Valgrind工具 Author: Once Day Date: 2025年3月26日 一位热衷于Linux学习和开发的菜鸟&#xff0c;试图谱写一场冒险之旅&#xff0c;也许终点只是一场白日梦… 漫漫长路&#xff0c;有人对你微笑过嘛… 全系列文章请查看专栏: Linux实践记录_Once-Day的博客-CSD…

强大的AI网站推荐(第四集)—— Gamma

网站&#xff1a;Gamma 号称&#xff1a;展示创意的新媒介 博主评价&#xff1a;快速展示创意&#xff0c;重点是展示&#xff0c;在几秒钟内快速生成幻灯片、网站、文档等内容 推荐指数&#xff1a;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;&#x…

《熔化焊接与热切割作业》考试注意事项

考试前的准备 携带必要的证件和材料&#xff1a;考生需携带身份证、准考证等有效证件&#xff0c;以及考试所需的焊接工具、材料等。确保证件齐全&#xff0c;避免因证件问题影响考试。 提前检查焊接设备和工具&#xff1a;在考试前&#xff0c;考生应仔细检查焊接设备和工具是…

[unity 点击事件] 区域响应点击事件,排除子节点区域,Raycast Target 应用

当我打开一个二级弹窗后&#xff0c;希望可以通过点击弹窗以外的区域来关闭该弹窗。一开始我是在弹窗主节点上挂载了一个 button 组件&#xff0c;该 button 注册的点击事件中关闭该弹窗。在子节点&#xff08;一个背景图&#xff09;的image组件上启用 Raycast Target 选项&am…

鸿蒙生态全解析:应用适配分享

一、鸿蒙系统的技术底座与适配挑战 HarmonyOS NEXT 作为全场景分布式操作系统&#xff0c;通过统一的技术底座和声明式开发框架&#xff0c;实现了 "一次开发&#xff0c;多端部署" 的跨设备协同能力。其核心优势在于&#xff1a; 弹性部署架构&#xff1a;一套系统…

el-select 可搜索下拉框 在ios、ipad 无法唤出键盘,造成无法输入

下一篇&#xff1a;el-select 可搜索下拉框&#xff0c;选中选项后&#xff0c;希望立即失去焦点&#xff0c;收起键盘&#xff0c;执行其他逻辑 【效果图】&#xff1a;分组展示选项 >【去界面操作体验】 首先&#xff0c;通过 夸克浏览器的搜索: el-select 在 ipad 输入框…

Axure设计之中继器表格——拖动列调整位置教程(中继器)

一、原理介绍 实现表格列的拖动排序&#xff0c;主要依赖Axure的动态面板和中继器两大核心功能&#xff1a; 动态面板交互控制 将表格的列标题封装在动态面板中&#xff0c;通过拖拽事件&#xff08;开始、移动、结束&#xff09;捕捉用户操作 在拖拽过程中实时计算鼠标位置&…

基于大数据的各品牌手机销量数据可视化分析系统(源码+lw+部署文档+讲解),源码可白嫖!

摘要 时代在飞速进步&#xff0c;每个行业都在努力发展现在先进技术&#xff0c;通过这些先进的技术来提高自己的水平和优势&#xff0c;各品牌手机销量数据可视化分析系统当然不能排除在外。基于大数据的各品牌手机销量数据可视化分析系统是在实际应用和软件工程的开发原理之…

Open CASCADE学习|基于AIS_PointCloud显示点集

定义与用途 AIS_PointCloud是OpenCASCADE中用于表示和管理点云数据的类&#xff0c;能够高效地绘制大量任意彩色点集。它通过Graphic3d_ArrayOfPoints将点数据传递给OpenGL图形驱动程序&#xff0c;以将设定点绘制为“点精灵”数组&#xff0c;且点数据被打包到顶点缓冲区对象…

GOC作业

实验室logo 题目描述 绘制烧毁实验室logo&#xff0c;它是由半径120&#xff0c;颜色6号色的空心元构成&#xff0c;中间的图案由线段长度为75&#xff0c;半径为15的实心圆构成&#xff0c;颜色从1号色开始&#xff0c;到6号色&#xff0c;如图所示 代码参考&#xff1a; …

本地部署仓库管理工具 Gitlab 并实现外部访问

Gitlab是一款自托管的 Git 仓库管理工具&#xff0c;它提供了完整的代码管理功能&#xff0c;包括代码托管、版本控制、代码合并请求、问题追踪、持续集成等。 本文将详细的介绍如何利用 Docker 在本地部署 Gitlab 并结合路由侠实现外网访问本地部署的 Gitlab 。‌ 第一步&am…

华鲲振宇天工TG225 B1国产服务器试装openEuler22.03 -SP4系统

今天测试了一下在华鲲振宇公司的天工TG225 B1国产服务器上进行openEuler22.03 -SP4操作系统的试装&#xff0c;本文记录整个测试过程。 一、服务器信息 1、服务器型号 Huakun TG225 B1 (D) 2、登录IPMI帐户信息 初始用户名Tech.ON 密码TianGong8000 二、磁盘RAID配置 测试…

linux常用指令(9)

加油同志们,我们离胜利不远了,再有两天我们就可以了解完linux的一些基本常用指令了,到时我们便可以进入一些shell脚本语法了,那么话不多说,来看. 1.more指令 功能描述&#xff1a;more指令是一个基于vi编辑器的文本过滤器,它以全屏幕的方式按页显示文本文件的内容. 基本语法…