【韩老师零基础30天学会Java 05】猜拳游戏 idea快捷键 动态绑定 equal instanceof finalize 断点调试 静态和普通代码块 main方法

本文介绍了一个简单的Java猜拳游戏实现,包括玩家与系统的交互逻辑,并探讨了Java开发中的快捷键使用、代码补全、动态绑定机制、类变量共享、构造器补充、代码块执行顺序等基础知识。此外,还提到了IDEA和Eclipse的常用快捷键,以及对象的`equals()`和`toString()`方法的重写。文章旨在帮助初学者提升开发效率和理解Java编程概念。
摘要由CSDN通过智能技术生成

猜拳 我的实现

        Random r = new Random();

        //boolean b = false;

        for (int i = 0; i < 10; i++) {

            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println("请输入0-石头,1-剪刀,2-布");

            int rd = r.nextInt(3);

            int tom = new Scanner(System.in).nextInt();

            //0石头,1剪刀 2布
            /*if (i == 1 && tom == 2) {
                b = false;
            }
            if (b) {
                if (tom - rd == -1 || tom - rd == 2) {
                    //tom胜的,先不管。
                } else {
                    //如果 tom为 布。
                    if (tom == 2) {
                        //系统为 石头
                        rd = 0;
                    } else {
                        //否则。系统为 tom+1;系统永远输
                        rd = tom + 1;
                    }
                }
            }*/

            if (tom == 0) {
                System.out.println("你出的是 石头");
            } else if (tom == 1) {
                System.out.println("你出的是 剪刀");
            } else {
                System.out.println("你出的是 布");
            }
            if (rd == 0) {
                System.out.println("系统的是 石头");
            } else if (rd == 1) {
                System.out.println("系统的是 剪刀");
            } else {
                System.out.println("系统的是 布");
            }

            if (rd == tom) {
                System.out.println("平局");
            } else if (tom - rd == -1 || tom - rd == 2) {
                //你出是 石头,或者 剪刀。 你出是布
                System.out.println("你赢了");
            } else {
                //你出是石头,对方是 布。
                System.out.println("你输了");
            }
            /*if (rd == tom) {
                System.out.println("平局");
            } else if (tom == 0 && rd == 1) {
                System.out.println("你赢了");
            } else if (tom == 1 && rd == 2) {
                System.out.println("你赢了");
            } else if (tom == 2 && rd == 0) {
                System.out.println("你赢了");
            } else {
                System.out.println("你输了");
            }*/
            System.out.println("----------------------");
        }

idea使用

快捷键

1.删除当前行,自己配置ctrl + d
2.复制当前行,自己配置ctrl + alt+向下光标3.补全代码alt+/
4、添加注释和取消注释 ctrl +/【第一次是添加注释,第二次是取消注释】

6.快速格式化代本ctrl + alt +L

7.快速运行程序自己定义alt +R

8.生成构造器等alt + insert[提高开发效率]
9.查看一个类的层级关系ctrl+H[学习继承后,非常有用]

  • 就是 结构窗口,alt+7

10.将光标放在一个方法上,输入ctrl + B,可以选择定位到哪个类的方法[学继承后,非常有用]

  • Eclips 快捷键模式,按住Ctrl单击 或 ctrl+T

11.自动的分配变量名,通过在后面.var

●模板/自定义模板
·file -> settings -> editor->Live templates ->查看有哪些模板快捷键/可以自己增加模板

动态绑定

属性看编译类型,方法看运行类型

public class PolyExercise02 {
    public static void main(String[] args) {
        Sub s = new Sub();
        System.out.println(s.count);//20
        s.display();//20
        Base b = s;
        System.out.println(b == s);//T
        System.out.println(b.count);//10
        b.display();//20
    }

}

class Base {//父类
    int count = 10;

    public void display() {
        System.out.println(this.count);
    }
}

class Sub extends Base {//子类
    int count = 20;

    public void display() {
        System.out.println(this.count);
    }
}

调用自己的方法和属性

public class DynamicBinding {
    public static void main(String[] args) {
        //a 的编译类型 A, 运行类型 B
        A a = new B();//向上转型
        System.out.println(a.i);
        System.out.println(a.sum());//?40
        System.out.println(a.sum1());//?30
        
//10
//40
//30
    }
}

class A {//父类
    public int i = 10;
    //动态绑定机制:

    public int sum() {//父类sum()
        return getI() + 10;//20 + 10
    }

    public int sum1() {//父类sum1()
        return i + 10;//10 + 10
    }

    public int getI() {//父类getI
        return i;
    }
}

class B extends A {//子类
    public int i = 20;

    public int sum() {
        return i + 20;
    }

    public int getI() {//子类getI()
        return i;
    }

    public int sum1() {
        return i + 10;
    }
}
	/*public int sum() {
        return i + 20;
    }*/

	/*public int sum1() {
        return i + 10;
    }*/

10
30 //getI获取的是子类的 20
20 //直接用 i,用的是 编译类型的,A类的i为10

java的动态绑定机制
1.当调用对象方法的时候,该方法会和该对象的内
存地址/运行类型绑定
2.当调用对象属性时,没有动态绑定机制,哪里声
明,那里使用

instanceof

        Person[] persons = new Person[5];
        persons[0] = new Person("jack", 20);
        persons[1] = new Student("mary", 18, 100);
        persons[2] = new Student("smith", 19, 30.1);
        persons[3] = new Teacher("scott", 30, 20000);
        persons[4] = new Teacher("king", 50, 25000);

        //循环遍历多态数组,调用say
        for (int i = 0; i < persons.length; i++) {
            //老师提示: person[i] 编译类型是 Person ,运行类型是是根据实际情况有JVM来判断
            System.out.println(persons[i].say());//动态绑定机制
            //这里大家聪明. 使用 类型判断 + 向下转型.
            if(persons[i]  instanceof  Student) {//判断person[i] 的运行类型是不是Student
                Student student = (Student)persons[i];//向下转型
                student.study();
                //小伙伴也可以使用一条语句 ((Student)persons[i]).study();
            } else if(persons[i] instanceof  Teacher) {
                Teacher teacher = (Teacher)persons[i];
                teacher.teach();
            } else if(persons[i] instanceof  Person){
                //System.out.println("你的类型有误, 请自己检查...");
            } else {
                System.out.println("你的类型有误, 请自己检查...");
            }

        }

String equals

        //把Object的equals方法重写了,变成了比较两个字符串值是否相同
        public boolean equals(Object anObject) {
        if (this == anObject) {//如果是同一个对象
            return true;//返回true
        }
            
        if (anObject instanceof String) {//判断类型
            String anotherString = (String)anObject;//向下转型
            int n = value.length;
            if (n == anotherString.value.length) {//如果长度相同
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {//然后一个一个的比较字符
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;//如果两个字符串的所有字符都相等,则返回true
            }
        }
        
        return false;//如果比较的不是字符串,则直接返回false
    }
    public boolean equals(Object obj) {
        return (this == obj);
    }//object类的
    
	//Integer 类型的
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

对象重写 equals

    //重写Object 的 equals方法
    public boolean equals(Object obj) {
        //判断如果比较的两个对象是同一个对象,则直接返回true
        if(this == obj) {
            return true;
        }
        //类型判断
        if(obj instanceof  Person) {//是Person,我们才比较

            //进行 向下转型, 因为我需要得到obj的 各个属性
            Person p = (Person)obj;
            return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;
        }
        //如果不是Person ,则直接返回false
        return false;

    }

toString源码

// Object的toString() 源码
        (1)getClass().getName() 类的全类名(包名+类名 )
        (2)Integer.toHexString(hashCode()) 将对象的hashCode值转成16进制字符串
            
        public String toString() {
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
        }

finalize()

1.当对象被回收时,系统自动调用该对象的finalize方法。子类可以重写该方法,
做一些释放资源的揉作

·2.什么时候被回收:当某个对象没有任何引用时,则jvm就认为这个对象是一个垃
圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会先调用finalize方法。

3.垃圾回收机制的调用,是由系统来决定(即有自己的GC算法).
也可以通过System.gc() 主动触发垃圾回收机制,

//演示 Finalize的用法
public class Finalize_ {
    public static void main(String[] args) {

        Car bmw = new Car("宝马");
        //这时 car对象就是一个垃圾,垃圾回收器就会回收(销毁)对象, 在销毁对象前,会调用该对象的finalize方法
        //,程序员就可以在 finalize中,写自己的业务逻辑代码(比如释放资源:数据库连接,或者打开文件..)
        //,如果程序员不重写 finalize,那么就会调用 Object类的 finalize, 即默认处理
        //,如果程序员重写了finalize, 就可以实现自己的逻辑
        bmw = null;
        System.gc();//主动调用垃圾回收器

        System.out.println("程序退出了....");
    }
}
class Car {
    private String name;
    //属性, 资源。。
    public Car(String name) {
        this.name = name;
    }
    //重写finalize
    @Override
    protected void finalize() throws Throwable {
        System.out.println("我们销毁 汽车" + name );
        System.out.println("释放了某些资源...");

    }
}
程序退出了....
我们销毁 汽车宝马
释放了某些资源...

断点调试

F7跳入),跳入方法内

F8(跳过),逐行执行代码

shift+F8(跳出),跳出方法

F9(resume,执行到下一个断点)

类静态变量

public class ChildGame {

    public static void main(String[] args) {

        Child child1 = new Child("白骨精");
        child1.join();
        child1.count++;

        Child child2 = new Child("狐狸精");
        child2.join();
        child2.count++;

        //类变量,可以通过类名来访问
        System.out.println("共有" + Child.count  + " 小孩加入了游戏...");

        System.out.println("child1.count=" + child1.count);//3
        System.out.println("child2.count=" + child2.count);//3
    }
}

class Child { //类
    private String name;
    
    //定义一个变量 count ,是一个类变量(静态变量) static 静态
    //该变量最大的特点就是会被Child 类的所有的对象实例共享
    public static  int count = 0;
    
    public Child(String name) {
        this.name = name;
    }
}

所有的类,都指向这一个变量。

共识(1) static变量是同一个类所有对象共享(2) static类变量,在类加载的时候就生成了.

  1. 堆里的一块 公共区域。JDK8和以后
    1. 类对应的 class对象,最后加载
    2. 可以看到static变量保存在Class 实例的尾部。
    3. Class对象确实在堆中。
  2. 放在 方法区的 一个块 静态域里。JDK8以前。

main方法接收参数

D: \javacode>java Hello tom jack smith
第1个参数=tom

idea 项目的运行文件,设置里:

VM options:
Program arguments:北京 上海 天津 tom jack

代码块

1)相当于另外一种形式的构造器(对构造器的补充机制),可以做初始化的操作
2)场景:如果多个构造器中都有重复的语句,可以抽取到初始化块中,提高代码的重用性

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

        Movie movie = new Movie("你好,李焕英");
        System.out.println("===============");
        Movie movie2 = new Movie("唐探3", 100, "陈思诚");
    }
}

class Movie {
    private String name;
    private double price;
    private String director;

    //3个构造器-》重载
    //老韩解读
    //(1) 下面的三个构造器都有相同的语句
    //(2) 这样代码看起来比较冗余
    //(3) 这时我们可以把相同的语句,放入到一个代码块中,即可
    //(4) 这样当我们不管调用哪个构造器,创建对象,都会先调用代码块的内容
    		//如果是静态代码块,只调用一次。
    //(5) 代码块调用的顺序优先于构造器..
    {
        System.out.println("电影屏幕打开...");
        System.out.println("广告开始...");
        System.out.println("电影正是开始...");
    };

    public Movie(String name) {
        System.out.println("Movie(String name) 被调用...");
        this.name = name;
    }

    public Movie(String name, double price) {

        this.name = name;
        this.price = price;
    }
}
电影屏幕打开...
广告开始...
电影正是开始...
Movie(String name) 被调用...
===============

static代码块也叫静态代码块,作用就是对类进行初始化,而且它随
着类的加载而执行,并且只会执行一次。如果是普通代码块,每创建一个对象,就执行。

类什么时候被加载[重要背!]

1 创建对象实例时(new)
2 创建子类对象实例,父类也会被加载
3 使用类的静态成员时(静态属性,静态方法)

  • 会先 加载父类的 静态代码块 (先初始化父类)

如果只是使用类的静态成员时,普通代码块并不会执行

  • 普通代码块,在new对象时,被调用,而且是每创建一个对象,就调用一次
    • 普通代码块,是 构造器的补充。构造器 被调用,才被调用。

静态和普通代码块

public class CodeBlockDetail02 {
    public static void main(String[] args) {
        A a = new A();// (1) A 静态代码块01 (2) getN1被调用...(3)A 普通代码块01(4)getN2被调用...(5)A() 构造器被调用
    }
}

class A {
    { //普通代码块
        System.out.println("A 普通代码块01");
    }
    private int n2 = getN2();//普通属性的初始化


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

    //静态属性的初始化
    private static  int n1 = getN1();

    public static int getN1() {
        System.out.println("getN1被调用...");
        return 100;
    }
    public int getN2() { //普通方法/非静态方法
        System.out.println("getN2被调用...");
        return 200;
    }

    //无参构造器
    public A() {
        System.out.println("A() 构造器被调用");
    }

}

1调用静态代码块和静态属性初始化(注意:静态代码块和静态属性初始化调用的优先级一样,如果有多个静态代码块和多个静态变量初始化,则按他们定义的顺序调用)

②调用普通代码块和普通属性的初始化(注意:普通代码块和普通属性初始化调用的优先级一样,如果有多个普通代码块和多个普通属性初始化,则按定义顺序调用)
③调用构造方法。

有子类和父类的时候

我们看一下创建一个子类对象时(继承关系),他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:

1父类的静态代码块和静态属性(优先级一样,按定义顺序执行)

子类的静态代码块和静态属性(优先级一样,按定义顺序执行)

③父类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)

4父类的构造方法

子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)

子类的构造方法/面试题

普通代码块 调用所有

class C02 {
    private int n1 = 100;
    private static  int n2 = 200;

    private void m1() {

    }
    private static void m2() {

    }

    static {
        //静态代码块,只能调用静态成员
        //System.out.println(n1);错误
        System.out.println(n2);//ok
        //m1();//错误
        m2();
    }
    {
        //普通代码块,可以使用任意成员
        System.out.println(n1);
        System.out.println(n2);//ok
        m1();
        m2();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值