【韩顺平Java笔记】第7章:面向对象编程(基础部分)【227-261】

news2024/11/24 15:42:27

文章目录

  • 227. 重载介绍
  • 228. 重载快速入门
  • 229. 重载使用细节
  • 230. 重载课堂练习1
  • 231. 232. 重载课堂练习2,3
  • 233. 可变参数使用
    • 233.1 基本概念
    • 233.2 基本语法
    • 233.3 快速入门案例
  • 234. 可变参数细节
  • 235. 可变参数练习
  • 236. 作用域基本使用
  • 237. 作用域使用细节1
  • 238. 作用域使用细节2
  • 239. 构造器基本介绍
  • 240. 构造器快速入门
  • 241. 构造器使用细节1
  • 242. 构造器使用细节2
  • 243. 构造器课堂练习
  • 244. 对象创建的流程分析
  • 245. 引出this
  • 246. this入门
  • 247. this本质
  • 248. this小结
  • 249. this使用细节
  • 250. this课堂练习
  • 251. 252. 本章作业1,2
  • 254. 255. 256. 本章作业4,5,6
  • 257. 本章作业7
  • 258. 本章作业8
  • 259. 本章作业9
  • 260. 本章作业10
  • 261. 本章作业11

227. 重载介绍

方法重载(OverLoad)
java 中允许同一个类中,多个同名方法的存在,但要求 形参列表不一致!
比如:System.out.println(); out 是 PrintStream 类型

重载的好处

  1. 减轻了起名的麻烦
  2. 减轻了记名的麻烦

228. 重载快速入门

案例:类:MyCalculator 方法:calculate

  1. calculate(int n1, int n2) //两个整数的和
  2. calculate(int n1, double n2) //一个整数,一个 double 的和
  3. calculate(double n2, int n1)//一个 double ,一个 Int 和
  4. calculate(int n1, int n2,int n3)//三个 int 的和
public class TestUse {
    public static void main(String[] args) {
        // System.out.println(100);
        // System.out.println("hello,world");
        // System.out.println('h');
        // System.out.println(1.1);
        // System.out.println(true);
        //
        MyCalculator mc = new MyCalculator();
        System.out.println(mc.calculate(1, 2));
        System.out.println(mc.calculate(1.1, 2));
        System.out.println(mc.calculate(1, 2.1));
    }
}
class MyCalculator{
    //下面的四个 calculate 方法构成了重载
    //两个整数的和
    public int calculate(int n1, int n2){
        System.out.println("calculate(int n1, int n2) 被调用");
        return n1 + n2;
    }
    //没有构成方法重载, 仍然是错误的,因为是方法的重复定义
    // public void calculate(int n1, int n2) {
    // System.out.println("calculate(int n1, int n2) 被调用");
    // int res = n1 + n2;
    // }
    //看看下面是否构成重载, 没有构成,而是方法的重复定义,就错了
    // public int calculate(int a1, int a2) {
    // System.out.println("calculate(int n1, int n2) 被调用");
    // return a1 + a2;
    // }
    //一个整数,一个 double 的和
    public double calculate(int n1, double n2) {
        return n1 + n2;
    }
    //一个 double ,一个 Int 和
    public double calculate(double n1, int n2) {
        System.out.println("calculate(double n1, int n2) 被调用..");
        return n1 + n2;
    }
    //三个 int 的和
    public int calculate(int n1, int n2,int n3){
        return n1 + n2 + n2;
    }
}

运行结果:
calculate(int n1, int n2) 被调用
3
calculate(double n1, int n2) 被调用…
3.1
3.1

229. 重载使用细节

230. 重载课堂练习1


f方法名和参数完全相同,虽然返回值不同,但是这不是重载,这是方法的重复定义。

231. 232. 重载课堂练习2,3

public class TestUse {
    public static void main(String[] args) {
        //在主类的 main ()方法中分别用参数区别调用三个方法
        Methods method = new Methods();
        method.m(10);//100
        method.m(10, 20);//200
        method.m("嗯嘛啊");//字符串信息
        //测试
        System.out.println(method.max(10, 24)); // 24
        System.out.println(method.max(10.0, 21.4)); // 21.4
        System.out.println(method.max(10.0, 1.4, 30.0)); // 30.0
    }
}
class Methods{
    public void m(int a){
        System.out.println("平方=" + (a * a));
    }
    public void m(int a, int b){
        System.out.println("相乘=" + (a * b));
    }
    public void m(String str){
        System.out.println(str);
    }
    public int max(int x1, int x2){
        return (x1 > x2) ? x1 : x2;
    }
    public double max(double x1, double x2){
        return (x1 > x2) ? x1 : x2;
    }
    public double max(double x1, double x2, double x3){
        return (x1 > x2) ? ((x1 > x3) ? x1 : x3) : ((x2 > x3) ? x2 : x3);
    }
}

运行结果:
平方=100
相乘=200
嗯嘛啊
24
21.4
30.0

233. 可变参数使用

233.1 基本概念

java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。
就可以通过可变参数实现

233.2 基本语法

访问修饰符 返回类型 方法名(数据类型… 形参名) {
}

233.3 快速入门案例

public class TestUse {
    public static void main(String[] args) {
        HspMethod m = new HspMethod();
        System.out.println(m.sum(1, 5, 100)); //106
        System.out.println(m.sum(1,19)); //20
    }
}
class HspMethod{
    //可以计算2,3,...,n个数的和
    //可以使用重载,但可变参数更好
    //int... 表示接受的是可变参数,类型是int, 即可以接收多个int(0-多)
    //使用可变参数时,可以当作数组来使用,即nums可以当作数组
    public int sum(int... nums){
        System.out.println("接收的参数个数:" + nums.length);
        int sum = 0;//求和变量
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        return sum;
    }
}

运行结果:
接收的参数个数:3
106
接收的参数个数:2
20

234. 可变参数细节


public class TestUse {
    public static void main(String[] args) {
        HspMethod m = new HspMethod();
        //细节:可变参数的实参可以为数组
        int[] arr = {1, 2, 3};
        System.out.println(m.sum(arr)); 
        //可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后
        System.out.println(m.sum("测试" ,arr));
        System.out.println(m.sum("测试" ,1,100));
    }
}
class HspMethod{
    //可以计算2,3,...,n个数的和
    //可以使用重载,但可变参数更好
    //int... 表示接受的是可变参数,类型是int, 即可以接收多个int(0-多)
    //使用可变参数时,可以当作数组来使用,即nums可以当作数组
    public int sum(int... nums){
        System.out.println("接收的参数个数:" + nums.length);
        int sum = 0;//求和变量
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        return sum;
    }
    //
    public int sum(String str, int... nums){
        System.out.println(str + "接收的参数个数:" + nums.length);
        int sum = 0;//求和变量
        for (int i = 0; i < nums.length; i++) {
            sum += nums[i];
        }
        return sum;
    }
}

运行结果:
接收的参数个数:3
6
测试接收的参数个数:3
6
测试接收的参数个数:2
101
【注】我这里用重载sum方法测试的,实际上写新方法也行。

235. 可变参数练习

public class TestUse {
    public static void main(String[] args) {
        HspMethod m = new HspMethod();
        System.out.println(m.showScore("milan" , 90.1, 80.0 ));
        System.out.println(m.showScore("terry" , 90.1, 80.0,10,30.5,70 ));
    }
}
class HspMethod{
    public String showScore(String name, double... scores){
        double sum = 0.0;//求和用
        for(int i =0; i< scores.length; i++){
            sum += scores[i];
        }
        return name + " 有 " +scores.length + "门课的成绩总分为=" + sum;
    }
}

运行结果:
milan 有 2门课的成绩总分为=170.1
terry 有 5门课的成绩总分为=280.6

236. 作用域基本使用

public class TestUse {
    public static void main(String[] args) {
        
    }
}
class Cat{
    //全局变量,属性
    //属性在定义时,可以直接赋值
    int age = 10;//指定的值是10
    {
        int num = 100;//不是属性,它定义在代码块中,局部变量必须赋值
    }
    double weight;//全局变量可以没有赋值,有默认值
    public void say(){
        //局部变量一般是指在成员方法中定义的变量
        //n和name的作用域在cry方法中
        int n = 10;
        String name = "jack";
        System.out.println("在cry中使用属性age=" + age);
    }
    public void eat(){
        System.out.println("在eat中使用属性age=" + age);
        // System.out.println("在eat中使用cry的变量name" + name);错误
        // System.out.println("在eat中使用变量num" + num);错误,它和成员不在一个作用域,它在单独的一个代码块中
    }
}

237. 作用域使用细节1




238. 作用域使用细节2



239. 构造器基本介绍

我们来看一个需求:前面我们在创建人类的对象时,是先把一个对象创建好后,再给他的年龄和姓名属性赋值,如果现在我要求,在创建人类的对象时,就直接指定这个对象的年龄和姓名,该怎么做? 这时就可以使用构造器。
基本语法
[修饰符] 方法名(形参列表){
方法体;
}

  1. 构造器的修饰符可以默认, 也可以是 public protected private
  2. 构造器没有返回值
  3. 方法名 和类名字必须一样
  4. 参数列表 和 成员方法一样的规则
  5. 构造器的调用, 由系统完成

构造方法又叫构造器(constructor),是类的一种特殊的方法,它的主要作用是完成对新对象的初始化。它有几个特点:

  1. 方法名和类名相同
  2. 没有返回值
  3. 在创建对象时,系统会自动的调用该类的构造器完成对象的初始化

240. 构造器快速入门

现在我们就用构造方法来完成刚才提出的问题:在创建人类的对象时,就直接指定这个对象的年龄和姓名。

public class TestUse {
    public static void main(String[] args) {
        //当我们 new 一个对象时,直接通过构造器指定名字和年龄
        Person p1 = new Person("田所浩二", 114514);
        System.out.println("p1 的信息如下");
        System.out.println("p1 对象 name=" + p1.name);
        System.out.println("p1 对象 age=" + p1.age);
    }
}
class Person{
    String name;
    int age;
    //1. 构造器没有返回值, 也不能写 void
    //2. 构造器的名称和类 Person 一样
    //3. (String pName, int pAge) 是构造器形参列表,规则和成员方法一样
    public Person(String pName, int pAge) {
        System.out.println("构造器被调用~~ 完成对象的属性初始化");
        name = pName;
        age = pAge;
    }
}

运行结果:
构造器被调用~~ 完成对象的属性初始化
p1 的信息如下
p1 对象 name=田所浩二
p1 对象 age=114514

241. 构造器使用细节1


【注】构造器执行的时候,对象已经创建了,它只是为了完成对象的初始化。

public class TestUse {
    public static void main(String[] args) {
        //当我们 new 一个对象时,直接通过构造器指定名字和年龄
        Person p1 = new Person("田所浩二", 114514);
        System.out.println("p1 的信息如下");
        System.out.println("p1 对象 name=" + p1.name);
        System.out.println("p1 对象 age=" + p1.age);
        Person p2 = new Person("德川");
        System.out.println("p2 的信息如下");
        System.out.println("p2 对象 name=" + p2.name);
        System.out.println("p2 对象 age=" + p2.age);
    }
}
class Person{
    String name;
    int age;
    public Person(String pName, int pAge) {
        System.out.println("构造器被调用~~ 完成对象的属性初始化");
        name = pName;
        age = pAge;
    }
    //构造器重载
    public Person(String pName){
        name = pName;
    }
}

运行结果:

构造器被调用~~ 完成对象的属性初始化
p1 的信息如下
p1 对象 name=田所浩二
p1 对象 age=114514
p2 的信息如下
p2 对象 name=德川
p2 对象 age=0

242. 构造器使用细节2

public class TestUse {
    public static void main(String[] args) {
        Dog dog = new Dog();
    }
}
class Dog{
    //系统自动生成默认构造器
    //使用javap反编译看看

}

先编译,然后反编译查看默认构造器:
D:\0JavaProject> javap Dog.class
Compiled from “TestUse.java”
class Dog {
Dog();
}

243. 构造器课堂练习

在前面定义的 Person 类中添加两个构造器:
第一个无参构造器:利用构造器设置所有人的 age 属性初始值都为 18
第二个带 pName 和 pAge 两个参数的构造器:使得每次创建 Person 对象的同时初始化对象的 age 属性值和 name 属性值。分别使用不同的构造器,创建对象.

public class TestUse {
    public static void main(String[] args) {
        //当我们 new 一个对象时,直接通过构造器指定名字和年龄
        Person p1 = new Person("田所浩二", 114514);
        System.out.println("p1 的信息如下");
        System.out.println("p1 对象 name=" + p1.name);
        System.out.println("p1 对象 age=" + p1.age);
        Person p2 = new Person();
        System.out.println("p2 的信息如下");
        System.out.println("p2 对象 name=" + p2.name);
        System.out.println("p2 对象 age=" + p2.age);
    }
}
class Person{
    String name;
    int age;
    Person(){
        age = 18;
    }
    public Person(String pName, int pAge) {
        name = pName;
        age = pAge;
    }
}

运行结果:
p1 的信息如下
p1 对象 name=田所浩二
p1 对象 age=114514
p2 的信息如下
p2 对象 name=null
p2 对象 age=18

244. 对象创建的流程分析


加载Person类信息,在堆中分配空间:

构造器调用后


245. 引出this

先看一段代码,并分析问题


246. this入门

247. this本质



jvm中的虚拟机地址不是实际地址,可以打印hashCode查看对象的虚拟“地址”

【问题】用通俗的语言简述一下Java中的jvm虚拟机地址(或者说jvm的逻辑地址),hashCode和物理地址
【GPT回答】在Java中,JVM(Java虚拟机)的逻辑地址、hashCode 和物理地址这三个概念指的是相关但不同的事物。我来用通俗的语言逐一解释这些概念:

  1. JVM的逻辑地址:VM的逻辑地址其实是指对象在JVM中的引用地址,或者说是对象在Java堆内存中的位置。这个地址是逻辑上的,意味着它是由JVM管理和使用的,对于Java程序来说,这个地址是看不到的,程序员通过引用来操作对象。
  2. hashCode:hashCode是Java中每个对象都可以有的一个整数值,它是通过调用对象的hashCode()方法获得的。这个值主要用于散列数据结构,比如HashMap,帮助快速定位和检索对象。需要注意的是,hashCode并不是内存地址,也不保证唯一性,它只是一个为了优化搜索和排序过程的计算结果。在Java中,每个对象都可以通过调用它的 hashCode() 方法来获取一个整数,这个整数可以被视为该对象的一个简单的数字标识。它通常用于快速检查对象的等同性,尤其是在哈希表(如 HashMap 或 HashSet)中存储对象时。hashCode 的计算方法依赖于对象的类型和内容,但它并不代表对象的内存地址。
  3. 物理地址:物理地址是计算机内存中的实际地址,这个地址指的是RAM(随机存取存储器)中的具体位置。对于Java程序员来说,这部分是完全透明的,由JVM和操作系统共同管理。Java程序中不可能直接访问物理地址。

总结一下,当你在Java中操作对象时,你用的是引用(可以视作JVM的逻辑地址),而对象的快速检索可能会用到hashCode,至于物理地址,那是在JVM之下由操作系统处理的,普通Java开发者无需也无法接触到。这样的设计抽象了底层的复杂性,让Java程序更容易编写和移植。



dog1对象和this输出的hashCode一致

248. this小结

this小结:简单的说,哪个对象调用,this就代表哪个对象。

249. this使用细节

  1. this 关键字可以用来访问本类的属性、方法、构造器
  2. this 用于区分当前类的属性和局部变量
  3. 访问成员方法的语法:this.方法名(参数列表);
  4. 访问构造器语法:this(参数列表); 注意只能在构造器中使用(即只能在构造器中访问另外一个构造器, 必须放在第一条语句)
  5. this 不能在类定义的外部使用,只能在类定义的方法中使用
public class TestUse {
    public static void main(String[] args) {
        T t1 = new T();
        t1.f2();
    }
}
class T{
    //细节:只能在构造器中用this调用另外一个构造器
    public T(){
        //this调用构造器必须放在第一条语句
        this("jack", 30);
        System.out.println("T()构造器");
        //在一个构造器中调用另外一个构造器
    }
    public T(String name, int age){
        System.out.println("T(String name, int age)构造器");
    }
    //细节:访问成员方法的语法:this.方法名(参数列表)
    public void f1(){
        System.out.println("f1() 方法..");
    }
    public void f2(){
        System.out.println("f2() 方法..");
        //调用本类的f1方法
        //第一种方式
        f1();
        //第二种方式
        this.f1();
    }
}

运行结果:
T(String name, int age)构造器
T()构造器
f2() 方法…
f1() 方法…
f1() 方法…

name是按就近原则找的,先找局部变量,找不到再找类的全局变量,this可以直接指定该对象的属性。

250. this课堂练习

定义 Person 类,里面有 name、age 属性,并提供 compareTo 比较方法,用于判断是否和另一个人相等,提供测试类 TestPerson(懒得改了,用TestUse类了)用于测试, 名字和年龄完全一样,就返回 true, 否则返回 false

public class TestUse {
    public static void main(String[] args) {
        Person p1 = new Person();
        Person p2 = new Person("丁真", 1919);
        Person p3 = new Person("田所浩二", 114514);
        if(p1.compareTo(p2)){
            System.out.println("p1==p2");
        }
        if(p1.compareTo(p3)){
            System.out.println("p1==p3");
        }
    }
}
class Person{
    String name;
    int age;
    public Person(){
        this("田所浩二", 114514);
    }
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    public boolean compareTo(Person person){
        return person.name.equals(this.name) && (person.age == this.age);
    }
}

运行结果:
p1==p3

251. 252. 本章作业1,2



public class TestUse {
    public static void main(String[] args) {
        double[] arr = {1.1, -0.9, 2.3};
        A01 a01 = new A01();
        Double res = a01.max(arr);
        if(res != null){
            System.out.println(res);
        }else{
            System.out.println("输入有误");
        }
        double[] arr1 = {};
        Double res1 = a01.max(arr1);
        if(res1 != null){
            System.out.println(res1);
        }else{
            System.out.println("输入有误或数组arr为空");
        }
        double[] arr2 = null;
        Double res2 = a01.max(arr2);
        if(res2 != null){
            System.out.println(res2);
        }else{
            System.out.println("输入有误或数组arr为空");
        }
        String[] sarr = {"ABC", "bcd", "aa"};
        A02 a02 = new A02();
        System.out.println(a02.find(sarr, "aa"));
        String[] sarr1 = {};
        Integer sres = a02.find(sarr1, "1");
        if(sres != null){
            System.out.println(sres);
        }else{
            System.out.println("输入有误或字符数组为空");
        }
        String[] sarr2 = null;
        Integer sres1 = a02.find(sarr2, "1");
        if(sres1 != null){
            System.out.println(sres1);
        }else{
            System.out.println("输入有误或字符数组为空");
        }
        Book book = new Book(120.0, "1");
        book.printInfo();
        book.updatePrice();
        book.printInfo();
        Book book1 = new Book(152.0, "2");
        book1.printInfo();
        book1.updatePrice();
        book1.printInfo();
        Book book2 = new Book(20.0, "3");
        book2.printInfo();
        book2.updatePrice();
        book2.printInfo();
    }
}
class A01{
    public Double max(double[] arr){
        //数组长度得大于0,否则返回空
        //数组的引用也不能为空
        if(arr == null || arr.length <= 0)
        {
            return null;
        }
        //假定第一个元素最大
        double maxD = arr[0];
        for (int i = 0; i < arr.length; i++) {
            if(arr[i] > maxD){
                maxD = arr[i];
            }
        }
        return maxD;
    }
}
class A02{
    public Integer find(String[] arr, String str){
        //数组长度得大于0,否则返回空
        //数组的引用也不能为空
        if(arr == null || arr.length <= 0)
        {
            return null;
        }
        int index = -1;//假定找不到,返回-1
        for (int i = 0; i < arr.length; i++) {
            if(arr[i].equals(str)){
                index = i;
            }
        }
        return index;
    }
}
class Book{
    double price;
    String name;
    public Book(double price, String name){
        this.price = price;
        this.name = name;
    }
    public void updatePrice(){
        if(this.price > 150.0){
            this.price = 150.0;
        }
        else if(this.price > 100 && this.price <= 150){
            this.price = 100.0;
        }
    }
    public void printInfo(){
        System.out.println(this.name + "的价格:" + this.price);
    }
}

运行结果:
2.3
输入有误或数组arr为空
输入有误或数组arr为空
2
输入有误或字符数组为空
输入有误或字符数组为空
1的价格:120.0
1的价格:100.0
2的价格:152.0
2的价格:150.0
3的价格:20.0
3的价格:20.0

254. 255. 256. 本章作业4,5,6



public class TestUse {
    public static void main(String[] args) {
        A03 a03 = new A03();
        int[] arr = {1, 2, 3};
        int[] arr1 = a03.copyArr(arr);
        arr1[0] = 114514;
        a03.printArr(arr);
        a03.printArr(arr1);
        Circle circle = new Circle(0.5);
        System.out.println("周长为:" + circle.printPerimeter());
        System.out.println("面积为:" + circle.printArea());
        Cale cale = new Cale(4,2);
        System.out.println("和=" + cale.sum());
        System.out.println("差=" + cale.minus());
        System.out.println("乘=" + cale.mul());
        Double divRes = cale.div();
        if(divRes != null){
            System.out.println("除=" + cale.div());
        }
        cale = new Cale(4,0);
        System.out.println("和=" + cale.sum());
        System.out.println("差=" + cale.minus());
        System.out.println("乘=" + cale.mul());
        divRes = cale.div();
        if(divRes != null){
            System.out.println("除=" + cale.div());
        }
    }
}
class A03{
    public int[] copyArr(int[] arr){
        //健壮性
        if(arr == null){
            return null;
        }
        int[] newArr = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            newArr[i] = arr[i];
        }
        return newArr;
    }
    //打印数组
    public void printArr(int[] arr){
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
        System.out.println();
    }
}
class Circle{
    double radius;
    public Circle(double radius){
        this.radius = radius;
    }
    //周长
    public double printPerimeter(){
        return 2 * radius * Math.PI;
    }
    //半径
    public double printArea(){
        return Math.PI * radius * radius;
    }
}
class Cale{
    double num1;
    double num2;
    public Cale(double num1, double num2){
        this.num1 = num1;
        this.num2 = num2;
    }
    //求和
    public double sum(){
        return num1 + num2;
    }
    //差
    public double minus(){
        return num1 - num2;
    }
    //乘
    public double mul(){
        return num1 * num2;
    }
    //除
    public Double div(){
        if(num2 == 0){
            System.out.println("除数不能为0");
            return null;
        }else{
            return num1 / num2;
        }
    }
}

运行结果:
1 2 3
114514 2 3
周长为:3.141592653589793
面积为:0.7853981633974483
和=6.0
差=2.0
乘=8.0
除=2.0
和=4.0
差=4.0
乘=0.0
除数不能为0

257. 本章作业7


7)代码:

public class TestUse {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.show();
    }
}
class Dog{
    String name;
    String color;
    int age;
    public Dog(){
        this("丁真", "雪豹色", 5);
    }
    public Dog(String name, String color, int age){
        this.name = name;
        this.color = color;
        this.age = age;
    }
    public void show(){
        System.out.println("名字:" + this.name);
        System.out.println("颜色:" + this.color);
        System.out.println("年龄:" + this.age);
    }
}

运行结果:
名字:丁真
颜色:雪豹色
年龄:5
8)
new Test()匿名对象

匿名对象的特点是只能用一次

【问题】用通俗的语言简述Java的匿名对象,及其如何分布在堆栈中的内存空间中
【GPT问答】Java 中的匿名对象是没有显式名称的对象。在编程过程中,我们通常为对象创建一个引用名(或者说变量名),这样我们就可以在后续的代码中多次使用这个对象。但有时候,为了某些只需临时使用一次的对象,我们可能会选择创建匿名对象。
什么是匿名对象?
举个简单的例子,如果我们通常创建一个按钮并给它添加一个点击监听器,可能会这样写:

Button myButton = new Button();
myButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        // 响应点击事件
    }
});

在这个例子中,OnClickListener 是一个接口,我们通常需要创建一个实现了这个接口的对象来处理点击事件。这里的 new OnClickListener() 创建了一个匿名类的对象,因为它没有被赋予一个具体的引用名。
匿名对象的内存分布
在 Java 中,内存主要分为两个部分:堆(Heap)和栈(Stack)。
: 这是用来存储所有创建的对象和它们的数据(属性)的地方,不管对象是否命名。匿名对象也是在堆上分配的。
: 这部分内存用来存储局部变量和方法调用的信息。局部变量可以包括指向堆中对象的引用。
当你创建一个匿名对象时,如 new OnClickListener(),实际上它在堆上分配了内存空间用来存储这个对象的状态和信息。但是,因为它是匿名的,你没有一个变量在栈上指向它。这意味着一旦这个匿名对象不被其他对象或方法引用,它就可以被垃圾回收机制回收了。
使用场景
匿名对象适用于那些只需要一次使用的场合。使用匿名对象可以让代码更简洁,但也需要注意,过度使用匿名对象可能会使代码的可读性降低,尤其是在匿名对象非常复杂的情况下。
总的来说,匿名对象是 Java 中一个非常有用的特性,可以用来快速创建对象而无需关心对象命名,同时它们如同其他对象一样占据堆内存,但在栈上没有对应的引用变量。

综上所述,输出结果是
10
9
10
后++是先执行(也就是题中代码的先输出)后自增

258. 本章作业8

9)代码:

public class TestUse {
    public static void main(String[] args) {
        Music music = new Music();
        music.play();
        System.out.println(music.getInfo());
    }
}
class Music{
    String name;
    double times;
    public Music(){
        this("只因你太美", 2.5);
    }
    public Music(String name, double times){
        this.name = name;
        this.times = times;
    }
    public void play(){
        System.out.println("音乐" + name + "正在播放中,时长为" + times + "秒");
    }
    public String getInfo(){
        return "音乐" + name +" 播放时间为" + times + "秒";
    }
}

运行结果:
音乐只因你太美正在播放中,时长为2.5秒
音乐只因你太美 播放时间为2.5秒
10)d2和d1指向同一个对象,d2.m()指向,int j=i++,先赋值后自增,即j为100,i为101,后面输出100 101,然后输出d1.i和d2.i都是101,所以输出结果是:
101
100
101
101

259. 本章作业9


11)如答案
12)代码

public class TestUse {
    public static void main(String[] args) {
        
    }
}
class Employee{
    String name;
    char gender;
    int age;
    String job;
    double sal;
    public Employee(String name, char gender, int age, String job, double sal){
        this(name, gender, age);//复用只能在第一行复用一次
        this.job = job;
        this.sal = sal;
    }
    public Employee(String name, char gender, int age){
        this.name = name;
        this.gender = gender;
        this.age = age;
    }
    public Employee(String job, double sal){
        this.job = job;
        this.sal = sal;
    }
}

260. 本章作业10

public class TestUse {
    public static void main(String[] args) {
        Circle c = new Circle();
        PassObject po = new PassObject();
        po.printAreas(c, 5);
    }
}
class Circle{
    double radius;
    public Circle(){
        this(1.0);
    }
    public Circle(double radius){
        this.radius = radius;
    }
    public double findArea(){
        return Math.PI * radius *radius;
    }
    //设置set方法
    public void setRadius(double radius){
        this.radius = radius;
    }
}
class PassObject{
    public void printAreas(Circle c, int times){
        System.out.println("Radius\tArea");
        for (int i = 1; i <= times; i++) {
            c.setRadius(i);
            System.out.println(i + "\t" + c.findArea());
        }
    }
}

运行结果:
Radius Area
1 3.141592653589793
2 12.566370614359172
3 28.274333882308138
4 50.26548245743669
5 78.53981633974483

261. 本章作业11

import java.util.Random;
import java.util.Scanner;
public class TestUse {
    public static void main(String[] args) {
        Game game = new Game();
        game.userGuess();
    }
}
//记录每局对局信息
class GameInfo{
    int botIn = 0;//电脑出拳的代号
    int userIn = 0;//玩家出拳代号
    public GameInfo(int botIn, int userIn){
        this.botIn = botIn;
        this.userIn = userIn;
    }
    //获取玩家出拳,默认出石头
    public String getUserIn(){
        switch(userIn){
            case 0:
                return "石头";
            case 1:
                return "剪刀";
            case 2:
                return "布";
            default:
                return "石头";
        }
    }
    //获取电脑出拳
    public String getBotIn(){
        switch(botIn){
            case 0:
                return "石头";
            case 1:
                return "剪刀";
            case 2:
                return "布";
            default:
                return "石头";
        }
    }
    //打印输赢情况
    //判断出拳输赢还是
    public void judge(){
        System.out.println("玩家出拳:" + getUserIn());
        System.out.println("电脑出拳:" + getBotIn());
        if(userIn == 0 && botIn == 1){
            System.out.println("玩家赢!");
        }
        else if(userIn == 1 && botIn == 2){
            System.out.println("玩家赢!");
        }
        else if(userIn == 2 && botIn == 0){
            System.out.println("玩家赢!");
        }
        else if(userIn == botIn){
            System.out.println("平手!");
        }
        else{
            System.out.println("玩家输!");
        }
    }
}
class Game{
    int botIn = 0;//电脑出拳的代号
    int userIn = 0;//玩家出拳代号
    int winNum = 0;//玩家总共赢了多少次
    GameInfo[] winListArr; //输赢清单
    //输出对局情况
    public void printWin(){
        System.out.println("=======总对局信息========");
        for (int i = 0; i < winListArr.length; i++) {
            System.out.println("=============");
            System.out.println("第" + (i+1) + "次对局如下:");
            winListArr[i].judge();
            System.out.println("=============");
        }
        System.out.println("玩家总共赢了" + winNum + "次");
    }
    public void botGuess(){
        //电脑先随机生成出什么拳
        Random r = new Random();
        int botGuessNum = r.nextInt(3);//返回0-2随机数
        botIn = botGuessNum;
    }
    //获取玩家出拳,默认出石头
    public String getUserIn(){
        switch(userIn){
            case 0:
                return "石头";
            case 1:
                return "剪刀";
            case 2:
                return "布";
            default:
                return "石头";
        }
    }
    //获取电脑出拳
    public String getBotIn(){
        switch(botIn){
            case 0:
                return "石头";
            case 1:
                return "剪刀";
            case 2:
                return "布";
            default:
                return "石头";
        }
    }
    public void userGuess(){
        //玩家出拳
        Scanner myScanner = new Scanner(System.in);
        do{
            System.out.println("请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏");
            userIn = myScanner.nextInt();
            if(userIn == 3){
                printWin();
            }
            if(userIn != 0 && userIn != 1 && userIn != 2){
                break;
            }
            System.out.println("玩家出拳:" + getUserIn());
            botGuess();
            System.out.println("电脑出拳:" + getBotIn());
            judge();
            //记录出拳信息到GameInfo类的动态数组
            //拷贝数组,然后替换引用来增加
            //如果开始winListArr是null引用
            //创建一个长度为1的
            //其他情况正常加入
            if(winListArr == null){
                winListArr = new GameInfo[1];
                winListArr[0] = new GameInfo(botIn, userIn);
            }else{
                GameInfo[] newArr = new GameInfo[winListArr.length + 1];
                for(int i = 0; i<winListArr.length; i++){
                newArr[i] = winListArr[i];
            }
            //在尾部加入新元素
            newArr[winListArr.length] = new GameInfo(botIn, userIn);
            //引用换到新数组,回收垃圾
            this.winListArr = newArr;
            }
        }while(true);
        System.out.println("游戏已退出");
    }
    //判断出拳输赢还是
    public void judge(){
        if(userIn == 0 && botIn == 1){
            System.out.println("玩家赢!");
            winNum++;
        }
        else if(userIn == 1 && botIn == 2){
            System.out.println("玩家赢!");
            winNum++;
        }
        else if(userIn == 2 && botIn == 0){
            System.out.println("玩家赢!");
            winNum++;
        }
        else if(userIn == botIn){
            System.out.println("平手!");
        }
        else{
            System.out.println("玩家输!");
        }
    }
}

运行结果:
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
1
玩家出拳:剪刀
电脑出拳:剪刀
平手!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
0
玩家出拳:石头
电脑出拳:石头
平手!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
1
玩家出拳:剪刀
电脑出拳:布
玩家赢!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
2
玩家出拳:布
电脑出拳:剪刀
玩家输!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
2
玩家出拳:布
电脑出拳:石头
玩家赢!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
2
玩家出拳:布
电脑出拳:布
平手!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
2
玩家出拳:布
电脑出拳:剪刀
玩家输!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
2
玩家出拳:布
电脑出拳:剪刀
玩家输!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
2
玩家出拳:布
电脑出拳:石头
玩家赢!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
1
玩家出拳:剪刀
电脑出拳:布
玩家赢!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
0
玩家出拳:石头
电脑出拳:布
玩家输!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
1
玩家出拳:剪刀
电脑出拳:布
玩家赢!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
2
玩家出拳:布
电脑出拳:布
平手!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
0
玩家出拳:石头
电脑出拳:剪刀
玩家赢!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
1
玩家出拳:剪刀
电脑出拳:石头
玩家输!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
1
玩家出拳:剪刀
电脑出拳:布
玩家赢!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
0
玩家出拳:石头
电脑出拳:剪刀
玩家赢!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
0
玩家出拳:石头
电脑出拳:剪刀
玩家赢!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
0
玩家出拳:石头
电脑出拳:石头
平手!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
0
玩家出拳:石头
电脑出拳:布
玩家输!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
1
玩家出拳:剪刀
电脑出拳:石头
玩家输!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
2
玩家出拳:布
电脑出拳:剪刀
玩家输!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
2
玩家出拳:布
电脑出拳:布
平手!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
2
玩家出拳:布
电脑出拳:石头
玩家赢!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
1
玩家出拳:剪刀
电脑出拳:石头
玩家输!
请出拳,输入0-石头,1-剪刀,2-布,3-查看输赢清单后退出游戏,其他-退出游戏
3
=======总对局信息========
=============
第1次对局如下:
玩家出拳:剪刀
电脑出拳:剪刀
平手!
=============
=============
第2次对局如下:
玩家出拳:石头
电脑出拳:石头
平手!
=============
=============
第3次对局如下:
玩家出拳:剪刀
电脑出拳:布
玩家赢!
=============
=============
第4次对局如下:
玩家出拳:布
电脑出拳:剪刀
玩家输!
=============
=============
第5次对局如下:
玩家出拳:布
电脑出拳:石头
玩家赢!
=============
=============
第6次对局如下:
玩家出拳:布
电脑出拳:布
平手!
=============
=============
第7次对局如下:
玩家出拳:布
电脑出拳:剪刀
玩家输!
=============
=============
第8次对局如下:
玩家出拳:布
电脑出拳:剪刀
玩家输!
=============
=============
第9次对局如下:
玩家出拳:布
电脑出拳:石头
玩家赢!
=============
=============
第10次对局如下:
玩家出拳:剪刀
电脑出拳:布
玩家赢!
=============
=============
第11次对局如下:
玩家出拳:石头
电脑出拳:布
玩家输!
=============
=============
第12次对局如下:
玩家出拳:剪刀
电脑出拳:布
玩家赢!
=============
=============
第13次对局如下:
玩家出拳:布
电脑出拳:布
平手!
=============
=============
第14次对局如下:
玩家出拳:石头
电脑出拳:剪刀
玩家赢!
=============
=============
第15次对局如下:
玩家出拳:剪刀
电脑出拳:石头
玩家输!
=============
=============
第16次对局如下:
玩家出拳:剪刀
电脑出拳:布
玩家赢!
=============
=============
第17次对局如下:
玩家出拳:石头
电脑出拳:剪刀
玩家赢!
=============
=============
第18次对局如下:
玩家出拳:石头
电脑出拳:剪刀
玩家赢!
=============
=============
第19次对局如下:
玩家出拳:石头
电脑出拳:石头
平手!
=============
=============
第20次对局如下:
玩家出拳:石头
电脑出拳:布
玩家输!
=============
=============
第21次对局如下:
玩家出拳:剪刀
电脑出拳:石头
玩家输!
=============
=============
第22次对局如下:
玩家出拳:布
电脑出拳:剪刀
玩家输!
=============
=============
第23次对局如下:
玩家出拳:布
电脑出拳:布
平手!
=============
=============
第24次对局如下:
玩家出拳:布
电脑出拳:石头
玩家赢!
=============
=============
第25次对局如下:
玩家出拳:剪刀
电脑出拳:石头
玩家输!
=============
玩家总共赢了10次
游戏已退出

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

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

相关文章

Docker安装部署和常用命令

Docker 是一种开源的平台&#xff0c;旨在帮助开发者和运维人员更轻松地创建、部署和运行应用程序。通过将应用程序及其依赖项打包到一个名为容器的标准化单位中&#xff0c;Docker 提供了一种轻量级的虚拟化解决方案。与传统虚拟机相比&#xff0c;Docker 容器可以在同一主机上…

GoogleNet原理与实战

在2014年的ImageNet图像识别挑战赛中&#xff0c;一个名叫GoogLeNet 的网络架构大放异彩。以前流行的网络使用小到11&#xff0c;大到77的卷积核。本文的一个观点是&#xff0c;有时使用不同大小的卷积核组合是有利的。 回到他那个图里面你会发现,这里的一个通过我们最大的池化…

12条职场经验总结

01 事干得好不好尚且不说&#xff0c;但是话一定要说得漂亮。 比如&#xff0c;当领导给你安排工作的时候&#xff0c;你一定要非常积极地响应&#xff0c;拍着胸脯跟领导说“放心吧”。至于后续到底怎么干&#xff0c;再结合实际情况有的放矢地把握。 02 当别人夸奖你的时…

记录使用crypto-js、jsencrypt实现js加密的方法

实用为主&#xff0c;直接上干货。 使用工具&#xff1a;pycharm专业版2020.3.2。 记录通过crypto-js模块、jsencrypt模块两种方式实现加密。 本文在pycharm中新建一个项目&#xff0c;一步一步记录实现步骤。 一、新建pycharm项目并新建两个js文件&#xff0c;分别命名为c…

Python 工具库每日推荐 【Requests】

文章目录 引言Python网络库的重要性今日推荐:Requests工具库主要功能:使用场景:安装与配置快速上手示例代码代码解释实际应用案例案例1:获取天气信息案例分析案例2:文件上传案例分析高级特性会话和Cookie处理自定义请求头超时设置代理设置扩展阅读与资源优缺点分析优点:缺…

Markdown 语法详解大全(超级版)(三)——甘特图语法详解

Markdown 语法详解大全(超级版)&#xff08;三&#xff09;——甘特图语法详解 Markdown 语法详解大全(超级版)&#xff08;一&#xff09; Markdown 语法详解大全(超级版)&#xff08;二&#xff09; Markdown 语法详解大全(超级版)&#xff08;三&#xff09; Markdown 语法…

[Linux#61][UDP] port | netstat | udp缓冲区 | stm32

目录 0. 预备知识 1. 端口号的划分范围 2. 认识知名端口号 3. netstat 命令 4. pidof 命令 二.UDP 0.协议的学习思路 1. UDP 协议报文格式 报头与端口映射&#xff1a; 2. UDP 的特点 面向数据报&#xff1a; 3. UDP 的缓冲区 4. UDP 使用注意事项 5. 基于 UDP 的…

栈的介绍与实现

一. 概念与结构 栈&#xff1a;⼀种特殊的线性表&#xff0c;其只允许在固定的⼀端进⾏插⼊和删除元素操作。进⾏数据插⼊和删除操作的⼀端称为栈顶&#xff0c;另⼀端称为栈底。栈中的数据元素遵守后进先出LIFO&#xff08;Last In First Out的原则。 压栈&#xff1a;栈的插…

平面电磁波(解麦克斯韦方程)电场相位是复数的积分常数,电场矢量每个分量都有一个相位。磁场相位和电场一样,这是因为无损介质中实数的波阻抗

注意无源代表你立方程那个点xyzt处没有源&#xff0c;电场磁场也是这个点的。 j电流面密度&#xff0c;电流除以单位面积&#xff0c;ρ电荷体密度&#xff0c;电荷除以单位体积。 j方程组有16个未知数&#xff0c;每个矢量有三个xyz分量&#xff0c;即三个未知数&#xff0c;…

k8s的简介和部署

一、k8s简介 在部署应用程序的方式上面&#xff0c;主要经历了三个阶段&#xff1a; 传统部署:互联网早期&#xff0c;会直接将应用程序部署在物理机上优点:简单&#xff0c;不需要其它技术的参与缺点:不能为应用程序定义资源使用边界&#xff0c;很难合理地分配计算资源&…

fiddler抓包18-1_导出jmeter脚本(jmx文件)

课程大纲 方法1 ① 下载2个扩展文件&#xff0c;FiddlerExtensions.dll和FiddlerExtensions.pdb&#xff0c;到Fiddler根目录中的“ImportExport”下&#xff0c;重启Fiddler。 下载链接: https://pan.baidu.com/s/1qtLoaiTd-VfHFb3UIPoSZw?pwdtwcu提取码: twcu ② Fiddler导…

UIAbility组件

一、作用 UIAbility组件是系统调度的基本单元,为应用提供绘制界面的窗口。一个应用可以包含一个或多个UIAbility组件 1、每一个UIAbility组件实例都会在最近任务列表中显示一个对应的任务。 如果开发者希望在任务视图中看到一个任务,建议使用“一个UIAbility+多个页面”的方…

Qt教程(002):Qt项目创建于框架介绍

二、创建Qt项目 2.1 创建项目 【1、New Project】 【2、选择Qt Widgets Application】 【3、设置项目名称和保存路径】 注意&#xff0c;项目名称和路径不要带中文。 【4、选择QWidget】 带菜单栏的窗口QMainWindow空白窗口QWidget对话框窗口QDialog 【5、编译】 2.2 项目框…

No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史

大家好&#xff01;作为一个喜欢探索本质的INTP&#xff0c;我整理了一份简明易懂的Web安全笔记。希望能帮助你轻松掌握这个领域的核心知识。 这份笔记涵盖了Web发展的历程&#xff0c;从静态的Web 1.0到智能化的Web 3.0。我们将探讨URL和HTTP协议&#xff0c;揭示它们在网络中…

【深度学习基础模型】神经图灵机(Neural Turing Machines, NTM)详细理解并附实现代码。

【深度学习基础模型】神经图灵机&#xff08;Neural Turing Machines, NTM&#xff09;详细理解并附实现代码。 【深度学习基础模型】神经图灵机&#xff08;Neural Turing Machines, NTM&#xff09;详细理解并附实现代码。 文章目录 【深度学习基础模型】神经图灵机&#xf…

利用条件概率解决“两个孩子的性别问题”

利用条件概率解决“两个孩子的性别问题”&#xff1a;深入分析与扩展 在日常生活中&#xff0c;概率问题常常会带来直观上的困惑&#xff0c;尤其是在涉及到条件概率的时候。今天我们讨论的这个问题是一个非常经典的例子&#xff1a;已知一对父母有两个孩子&#xff0c;其中一…

二叉树的中序&后序遍历——非递归版本

1.题目解析 题目来源&#xff1a;二叉树的中序遍历——力扣 测试用例 题目来源&#xff1a;二叉树的后序遍历——力扣 测试用例 2.算法原理 中序遍历 中序遍历&#xff1a;左子树->根节点->右子树 与之前前序遍历的思路基本相同&#xff0c;不过需要注意的是中序变量需要…

今日指数项目股票Code联想推荐功能实现

股票Code联想推荐 1 股票Code联想推荐功能介绍 1) 原型效果 输入框输入股票编码后&#xff0c;显示关联的股票信息; 2&#xff09;接口定义说明 接口说明&#xff1a; 功能描述&#xff1a;根据输入的个股代码&#xff0c;进行模糊查询&#xff0c;返回证券代码和证券名称…

Redis中GEO数据结构实现附近商户搜索

Redis的版本必须是6.2以上 在测试类中将数据导入Redis Testvoid loadShopData(){//1.查询店铺信息List<Shop> list shopService.list();//2.把店铺分组&#xff0c;按照typeId分组&#xff0c;typeId一致的放到一个集合Map<Long, List<Shop>> map list.s…