首页
统计
友链
关于
Search
1
静静地生活着
411 阅读
2
JVM_1.引言
401 阅读
3
Chapter 03
328 阅读
4
机器学习 01
318 阅读
5
欢迎使用 Typecho
280 阅读
Java
School
ML
Other
Share
Explore
运维
登录
Search
bbchen
累计撰写
53
篇文章
累计收到
5
条评论
首页
栏目
Java
School
ML
Other
Share
Explore
运维
页面
统计
友链
关于
搜索到
31
篇与
的结果
2023-02-26
Chapter10_OOP高级
面向对象编程(高级)本章内容类变量引入package com.bbedu.static_; public class ChildGame { public static void main(String[] args) { // 定义一个count int count = 0; Child ming = new Child("ming"); ming.join(); count++; Child qiang = new Child("qiang"); qiang.join(); count++; Child li = new Child("li"); li.join(); count++; System.out.println("共有" + count + "个人加入游戏"); } } class Child { private String name; public Child(String name) { this.name = name; } public void join() { System.out.println(name + " 加入了游戏..."); } }分析:count 是一个独立于对象,很尴尬以后我们访问 count 很麻烦, 没有使用到 OOP因此,我们引出 类变量/静态变量快速入门package com.bbedu.static_; public class ChildGame { public static void main(String[] args) { Child ming = new Child("ming"); ming.join(); Child qiang = new Child("qiang"); qiang.join(); Child li = new Child("li"); li.join(); // 类变量可以通过类名直接访问 System.out.println("共有" + Child.count + "个人加入游戏"); } } class Child { private String name; // 类变量,又叫静态变量 // 该变量最大的特点是会被所有的 Child 对象实例共享 public static int count = 0; public Child(String name) { this.name = name; } public void join() { System.out.println(name + " 加入了游戏..."); count++; } }理解静态变量被对象共享,在类加载中就生成了,JDK7以上版本,静态域存储于定义类型的 Class 对象中,Class 对象如同堆中其他对象一样,存在于 GC 堆中。因此不影响对静态变量的使用类变量又叫静态变量/静态属性,是该类的所有对象共享的变量,任何一个该类的独享去访问它,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的都是同一个变量定义类变量:访问修饰符 static 数据类型 变量名; [推荐]static 访问修饰符 数据类型 变量名;访问类变量:类名.类变量 [推荐]或者对象名.类变量细节什么时候使用类变量当我们需要让某个类的所有对象共享一个变量时,就可以考虑使用类变量类变量与实例变量(普通属性)的区别类变量是该类的所有对象共享的,而实例变量是每个对象独享的加上 static 称为类变量或静态变量,否则称为实例变量/普通变量/非静态变量类变量可以通过 类名.类变量名 或者 对象名.类变量名 来访问,但 java 设计者推荐使用 类名.类变量名 的方式来访问实例变量不能通过 类名.变量名 的方式来访问类变量是在类创建时就初始化了,也就是说,即使没有创建对象,只要类加载了,就可以使用类变量了类变量的生命周期是随着类的加载开始,随着类的消亡而销毁类方法基本介绍类方法也叫静态方法,形式如下:访问修饰符 static 返回数据类型 方法名(){ } [推荐]static 访问修饰符 返回数据类型 方法名(){ }类方法的调用:类名.类方法名 或 对象名.类方法名 (需要满足访问修饰符的访问权限和范围)类方法的使用场景:当方法中不涉及到任何和对象相关的成员,则可以讲方法设计成静态方法,提高开发效率如果我们希望不创建对象,也可以调用某个方法(即当作工具来使用),这时,把方法设计成静态方法非常合适比如,工具类中的方法 utils Math类、Arrays类、Collections集合类细节类方法和普通方法都是随着类的加载而加载,讲结构信息存储在方法区类方法可以通过类名调用,也可以通过对象名调用普通方法和对象有关,需要通过对象名调用,比如 对象名.方法(参数),不能通过类名调用类方法中不允许使用和对象有关的关键字,如 super 和 this,普通方法可以类方法中只能访问 静态变量 或 静态方法(静态方法只能访问静态成员)普通成员方法,既可以访问 非静态方法/普通变量(方法),也可以访问 静态方法/静态变量(方法)练习count=9count=1011id++; 错误输出:014main 方法理解 main 方法public static void main(String[] args){}main 方法是虚拟机调用java 虚拟机需要调用类的 main() 方法,所以该方法的访问权限必须是 publicjava 虚拟机在执行 main() 方法时,不必创建对象,所以方法必须是 static该方法接收 String 类型的数组参数,该数组中保存执行 java 命令时传递给所运行的类的参数java 执行的程序 参数1 参数2 参数3特别说明在 main() 方法中,我们可以直接调用 main 方法所在类的静态方法或静态属性但是,不能直接访问该类中的非静态成员,必须创建该类的有个实例对象后,才能通过这个对象去访问类中的非静态成员package com.bbedu.main_; public class Main01 { // 静态的属性 private static String name = "秋高气爽"; public static void hi(){ System.out.println("Main01 的 hi 方法"); } // 非静态成员 private int n1 = 10000; public void ok(){ System.out.println("Main01 的 ok 方法"); } public static void main(String[] args) { // 可以直接使用 name // 静态方法可以直接访问本类的静态成员 System.out.println("name=" + name); hi(); // 静态方法main不可以访问非静态成员 //System.out.println("n1=" + n1); // 错误 Main01 main01 = new Main01(); System.out.println("n1=" + main01.n1); main01.ok(); } }idea 中传值代码块代码化块又称为初始化块,属于类中的成员[即是类的一部分],类似于方法,将逻辑语句封装在方法体中,通过包围起来。但和方法不同,没有方法名,没有返回,没有参数,只有方法体,而且不用通过对象或类显式调用,而是加载类时,或创建对象时隐式调用。基本语法[修饰符]{ 代码}修饰符可选,要写的话,也只能写 static代码块分为两类,使用 static 修饰的叫静态代码块,没有 static 修饰的,叫普通代码块逻辑语句可以为任意逻辑语句(输入、输出、方法调用、循环、判断等); 号可以写,也可以忽略细节static 代码块也叫静态代码块,作用就是对类进行初始化,而且它随着类的加载而执行,并且只会执行一次。如果是普通代码块,每创建一个对象,就执行类声明时候被加载(1) 创建对象实例时 (new) (2) 创建子类对象实例,父类也会被加载 (3) 使用类的静态成员时 (静态属性、静态方法)普通的代码块,在创建对象实例是,会被隐式地调用。被创建一次,就会调用一次。如果只是使用类的静态成员,普通代码块并不会执行。可以把普通代码块简单的理解为构造器的补充创建一个对象时,在一个类中调用顺序是:调用静态代码块和静态属性初始化(若有多个静态代码块和多个静态变量初始化,则按顺序依次调用)调用普通代码块和普通属性的初始化(同上,若有多个,则按顺序)调用构造器构造方法(构造器) 的最前面隐含了 super() 和 调用普通代码块,静态相关的代码块,属性初始化,在类加载时,就执行完毕,因此是优先于构造器和普通代码块执行的创建子类对象时(继承关系),同名的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下:/面试题父类的静态代码块和静态属性(优先级一样,按定义顺序执行)子类的静态代码块和静态属性(优先级一样,按定义顺序执行)父类的普通代码块和普通属性初始化(优先级一样。按定义顺序执行)父类的构造方法子类的普通代码块和普通属性初始化(优先级一样,按定义顺序执行)子类的构造方法总结:父子静,父普构,子普构静态代码块只能调用静态成员,普通代码块可以调用所有成员练习输出:in static block!total = 100total = 100输出:静态成员sam初始化static块执行sam1成员初始化Test默认构造函数被调用单例设计模式什么是设计模式静态方法和属性的经典使用设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格以及解决问题的思考方式。设计模式就像是经典的棋谱,不同的棋局,我们用不同的棋谱,免去我们自己在思考和摸索什么是单例模式所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法单例模式有两种方式:饿汉式,懒汉式饿汉式构造器私有化 => 防止直接 new类的内部创建对象向外暴露一个静态的公共方法package com.bbedu.single_; public class SingleTon01 { public static void main(String[] args) { GirlFriend instance = GirlFriend.getInstance(); System.out.println(instance); GirlFriend instance1 = GirlFriend.getInstance(); System.out.println(instance1); System.out.println(instance == instance1); } } class GirlFriend { private String name; // 静态方法只能访问静态成员,因此 gf 需要为静态 private static GirlFriend gf = new GirlFriend("Mary"); // 保证我们只能创建一个 GirlFriend 对象 //1. 构造器私有化 => 防止直接 new //2. 类的内部创建对象 //3. 向外暴露一个静态的公共方法 private GirlFriend(String name){ this.name = name; } public static GirlFriend getInstance(){ return gf; } @Override public String toString() { return "GirlFriend{" + "name='" + name + '\'' + '}'; } } 懒汉式构造器私有化 => 防止直接 new类的内部创建对象向外暴露一个静态的公共方法只有当用户调用 getInstance 方法时,才创建对象实例package com.bbedu.single_; /** * 演示懒汉式的单例模式 */ public class SingleTon02 { public static void main(String[] args) { System.out.println(Cat.n1); Cat instance = Cat.getInstance(); System.out.println(instance); } } // 希望只能创建一个 Cat 对象 class Cat { public static int n1 = 888; private String name; private static Cat cat; private Cat(String name) { System.out.println("构造器被调用..."); this.name = name; } public static Cat getInstance(){ if (cat == null){ cat = new Cat("小花"); } return cat; } @Override public String toString() { return "Cat{" + "name='" + name + '\'' + '}'; } }区别:饿汉式 VS 懒汉式二者最主要的区别在于创建对象的时机不同:饿汉式是在类加载就创建了对象实例,而懒汉式是在使用时才创建。饿汉式不存在线程安全问题,懒汉式存在线程安全问题。(后面学习线程后,会完善)3. 饿汉式存在浪费资源的可能。因为如果程序员一个对象实例都没有使用,那么饿汉式创建的对象就浪费了,懒汉式是使用时才创建,就不存在这个问题。4. 在我们javaSE标准类中,java.lang.Runtime就是经典的单例模式。final 关键字final 可以修饰类、属性、方法和局部变量在某些情况下,程序员可能有以下需求,就会用到 final:当不希望类被继承时当不希望父类的某个方法被子类重写时当不希望类的某个属性的值被修改时当不希望某个局部变量被修改时细节final 修饰的属性又叫常量,一般用 XX_XX_XX来命名final 修饰的属性在定义时,必须赋初值,并且以后不能在修改,赋值可以在下面位置之一:定义时构造器中代码块中如果 final 修饰的属性是静态的,贼初始化的位置只能是:定义时在静态代码块,不能再构造器中赋值final 类不能继承,但是可以实例化对象如果类不是 final 类,但是含有 final 方法,则该方法虽然不能重写,但是可以被继承,即仍然遵守继承规则一般来说,如果一个类已经是 final 类了,就没必要再将方法修饰成 final 方法final 不能修饰构造方法final 和 static 往往搭配使用,效率更高,不会导致类的加载,底层编译器做了相关优化包装类(Integer,String,Double)是 final 类,不能被继承注意final 关键字只是表示存储在变量中的对象不会再指示另一个不同的对象,不过这个对象可以更改,例如:final char[] a = {'a', 'b', 'c'}; a[0] = 'd'; System.out.println(a);换句话说,final 修饰基本数据类型的话值是不能进行改变的,修饰引用类型的话就是指地址不能被改变而值可以进行修改,这个需要区分一下练习package com.bbedu.final_; public class FinalExercise01 { public static void main(String[] args) { Circle circle = new Circle(5); System.out.println(circle.area()); } } class Circle { private double radius; private final double PI_1 = 3.14; private final double PI_2; private final double PI_3; { PI_2 = 3.14; } public Circle(double radius){ this.radius = radius; PI_3 = 3.14; } public double area(){ return PI_1 * radius * radius; } }有误,x不可自增抽象类当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,那么这个类就是抽象类所谓抽象方法,就是没有实现的方法 => 没有方法体当一个类中存在抽象方法时,需要将该类声明为 abstract 类一般来说,抽象类会被继承,由其子类来实现抽象方法介绍用abstract关键字来修饰一个类时,这个类就叫抽象类访问修饰符abstract类名{}用abstract关键字来修饰一个方法时,这个方法就是抽象方法访问修饰符 abstract 返回类型方法名(参数列表);//没有方法体抽象类的价值更多作用是在于设计,是设计者设计好后,让子类继承并实现抽象类()抽象类,是考官比较爱问的知识点,在框架和设计模式使用较多细节抽象类不能实例化抽象类不一定要包含 abstract 方法一旦包含了 abstract 方法,则这个类必须声明为 abstractabstract 只能修饰类和方法,不能修饰属性和其他抽象类可以拥有任意成员(抽象类本质还是类),如:非抽象方法、构造方法、静态属性...抽象方法不能有主体,即不能实现如果一个类继承了抽象类,则它必须实现抽象类的所有抽象方法,除非它自己也声明为 abstract 类抽象方法不能使用 private final static 来修饰,因为这些关键字都是和重写违背的练习package com.bbedu.abstract_; abstract public class Employee { private String name; private int age; private double sal; public Employee(String name, int age, double sal) { this.name = name; this.age = age; this.sal = sal; } // 将 work 做成一个抽象方法 abstract public void work(); 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 double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } }package com.bbedu.abstract_; public class Manager extends Employee{ private double bonus; public Manager(String name, int age, double sal, double bonus) { super(name, age, sal); this.bonus = bonus; } public double getBonus() { return bonus; } public void setBonus(double bonus) { this.bonus = bonus; } @Override public void work() { System.out.println("经理" + getName() + "工作中..."); } }package com.bbedu.abstract_; public class CommonEmployee extends Employee{ public CommonEmployee(String name, int age, double sal) { super(name, age, sal); } @Override public void work() { System.out.println("普通员工" + getName() + "工作中..."); } }package com.bbedu.abstract_; public class AbstractExercise01 { public static void main(String[] args) { Manager tim = new Manager("Tim", 32, 600000, 5000); tim.work(); CommonEmployee rick = new CommonEmployee("Rick", 40, 50000); rick.work(); } }抽象类最佳实践-模板设计模式需求有多个类,完成不同的任务能够统计得到各自完成任务的时间package com.bbedu.abstract_; /** * 模板设计模式 */ abstract public class Template { public abstract void job(); public void calculateTime(){ long start = System.currentTimeMillis(); job(); long end = System.currentTimeMillis(); System.out.println("执行时间:" + (end - start)); } }package com.bbedu.abstract_; public class AA extends Template{ // 实现Template的抽象方法 public void job(){ long num = 0; for (long i = 1; i <= 1000000000; i++) { num += i; } System.out.println(num); } }package com.bbedu.abstract_; public class BB extends Template{ public void job(){ long num = 0; for (long i = 1; i <= 80000; i++) { num *= i; } System.out.println(num); } }package com.bbedu.abstract_; public class TestTemplate { public static void main(String[] args) { AA aa = new AA(); aa.calculateTime(); BB bb = new BB(); bb.calculateTime(); } }接口基本介绍就看就是给出一些没有实现的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。语法:interface 接口名{ // 属性 // 方法}class 类名 implements 接口 { 自己属性; 自己方法; 必须实现的接口的抽象方法;}在接口中,抽象方法可以省略 abstract 关键字在jdk8后,可以有默认实现方法,需要使用 default 关键字修饰;可以有静态方法细节接口不能被实例化接口中的所有方法都是 public 方法,接口中的抽象方法,可以不用 abstract 修饰一个普通类实现接口,就必须将该接口的所有方法都实现抽象类实现接口,可以不用实现接口的方法一个类可以同时实现多个接口接口中的属性,只能是 final 的,而且是 public static final 修饰符,比如 int a = 1; 实际上等价于 public static final int a = 1;(必须初始化)接口中属性的访问形式:接口名.属性名接口不能继承其他的类,但是可以继承多个别的接口练习都正确,输出:232323实现接口 vs 继承类当子类继承了父类,就自动的拥有了父类的功能,如果子类需要扩展功能,可以通过实现接口的方式来扩展可以理解:实现接口是对 java 单继承的一种补充接口和继承解决的问题不同继承的价值主要在于:解决代码的复用性和可维护性接口的价值主要在于:设计,设计好各种规范(方法),让其他类去实现这些方法,更加灵活继承是满足 is-a 的关系,而接口只需满足 like - a的关系接口在一定程度上实现代码解耦(即 接口规范性+动态绑定)接口的多态特性多态参数,接口类型的变量 可以指向 实现了此接口的对象实例 => 类比继承的向上转型多态数组,动态绑定 + 使用 instanceof 判断 + 向下转型多态传递,接口间继承,类实现时遵守继承规则练习pX() 中 x 不明确,A.x, super.x,输出为:01小结类的五大成员:属性方法构造器代码块*内部类内部类一个类的内部又完整地嵌套了另一个类结构,被嵌套的类成为内部类(inner class),嵌套其他类的类成为外部类(outer class)。内部类是java 类的第五大成员,内部类的最大特点是可以直接访问私有属性,并且可以体现类鱼类的包含关系。内部类是学习的重难点,底层源码中有大量的内部类基本语法class Outer{ // 外部类 class Inner{ // 内部类 }}class Other{ // 外部其他类}分类定义在外部类局部位置上:局部内部类(有类名)匿名内部类(没有类名,重点)定义在外部类的成员位置上:成员内部类(没用 static 修饰)静态内部类(使用 static 修饰)局部内部类局部内部类是定义在外部类的局部位置,通常在方法可以直接访问外部类的所有成员,包含私有的不能添加访问修饰符,但是可以使用 final 修饰作用域:仅仅在定义它的方法或代码块中局部内部类可以直接访问外部类的成员外部类在方法中,可以创建 Inner02 对象,然后调用方法即可如果外部类和局部内部类的成员重名时,默认就近原则,如果想访问外部类的成员,使用 外部类名.this.成员 去访问package com.bbedu.innerclass; /** * 演示局部内部类的使用 */ public class LocalInnerClass { public static void main(String[] args) { Outer02 outer02 = new Outer02(); outer02.m1(); System.out.println("Outer02 hashcode=" + outer02); } } class Outer02 { private int n1 = 100; private void m2() { System.out.println("Outer02 m2()"); } public void m1() { // 1.局部内部类是定义在外部类的局部位置,通常在方法 // 3.不能添加访问修饰符,但是可以使用 final 修饰 // 4.作用域:仅仅在定义它的方法或代码块中 class Inner02 { // 本质还是一个类 private int n1 = 999; public void f1() { // 2.可以直接访问外部类的所有成员,包含私有的 // 5.局部内部类可以直接访问外部类的成员,如下面的 n1 和 m2() System.out.println("n1=" + n1 + " 外部类的n1=" + Outer02.this.n1); System.out.println("Outer02.this hashcode=" + Outer02.this); m2(); } } class Inner03 extends Inner02 { } // 6.外部类在方法中,可以创建 Inner02 对象,如何调用方法即可 Inner02 inner02 = new Inner02(); inner02.f1(); } }匿名内部类(非常重要)本质是类内部类该类没有名字同时是一个对象基本语法new 类或接口(参数列表){ 类体;}细节匿名内部类的语法比较奇特。匿名内部类既是一个类的定义,同时它本身也是一个对象,因此从语法上看,它既有定义类的特性,也有创建对象的特征,因此可以调用匿名内部类方法可以直接访问外部类的所有成员,包含私有的不能添加访问修饰符,因为它的地位就是一个局部变量作用域:仅仅在定义它的方法或代码块中外部其他类不能访问匿名内部类外部类和匿名内部类的成员重名时,匿名内部类访问时,默认就近原则,如果想访问外部类的成员,使用 外部类名.this.成员 去访问package com.bbedu.innerclass; /** * 演示匿名内部类的使用 */ public class AnonymousInnerClassDetail { public static void main(String[] args) { Outer05 outer05 = new Outer05(); outer05.f1(); // 外部其他类不能访问匿名内部类 } } class Outer05 { private int n1 = 99; public void f1(){ // 创建一个基于类的匿名内部类 Person p = new Person(){ private int n1 = 66; @Override public void hi() { System.out.println("匿名内部类重写了 hi()"); System.out.println("n1 = " + n1 + "\nOuter05 n1 = " + Outer05.this.n1); } }; p.hi(); // 真实的运行类型为 Outer$1 // 第二种调用,直接调用匿名对象的 hi() 方法 // new Person(){ // @Override // public void hi() { // System.out.println("匿名内部类重写了 hi() 哈哈哈"); // } // // @Override // public void ok(String str) { // super.ok(str); // } // }.ok("Mary"); } } class Person { public void hi() { System.out.println("Person hi()"); } public void ok(String str){ System.out.println("Person ok() " + str); } } // 抽象类、接口...最佳实践当作实参直接传递,简洁高效package com.bbedu.innerclass; public class InnerClassExercise01 { public static void main(String[] args) { f1(new AA(){ @Override public void show() { System.out.println("这是一幅画"); } }); // 传统方法 f1(new Pic()); } // 静态方法 public static void f1(AA aa){ aa.show(); } } interface AA { void show(); } class Pic implements AA{ // 类实现AA -> 硬编码 @Override public void show() { System.out.println("这是一幅画"); } }package com.bbedu.innerclass; public class InnerClassExercise02 { public static void main(String[] args) { CellPhone cellPhone = new CellPhone(); // 传递的是实现了 Bell 接口的匿名内部类 cellPhone.alarmClock(new Bell() { @Override public void ring() { System.out.println("懒猪起床了!!"); } }); // 相当于: Bell bell = new Bell(){ @Override public void ring() { System.out.println("懒猪起床了!!"); } }; cellPhone.alarmClock(bell); cellPhone.alarmClock(new Bell() { @Override public void ring() { System.out.println("小伙伴上课了"); } }); } } interface Bell{ void ring(); } class CellPhone{ public void alarmClock(Bell bell){ bell.ring(); } }成员内部类定义在外部类的成员位置可以添加任意访问修饰符,因为它的地位就是一个成员作用域是整个外部类类体可以直接访问外部类成员要使用成员内部类,在外部类创建其实例,然后使用相关的方法外部其他类访问成员内部类:两种方法,详见代码重名遵守就近原则,如果想访问外部类的成员,使用 外部类名.this.成员 去访问package com.bbedu.innerclass; public class MemberInnerClass01 { public static void main(String[] args) { Outer08 outer08 = new Outer08(); outer08.t1(); // 外部其他类,使用衬衣内部类的两种方式 // 1、相当于把 new Inner08() 当作是 outer08 的成员,不必纠结 Outer08.Inner08 inner08 = outer08.new Inner08(); inner08.say(); // 2.在外部类中编写一个方法,可以返回 Inner08 的一个对象实例 Outer08.Inner08 inner081 = outer08.getInner08Instance(); inner081.say(); // 3.把new 外部类 和 方法1 合起来 } } class Outer08{ private int n1 = 100; public String name = "张三"; class Inner08 { // 成员内部类 private int sal = 999; private int n1 = 66; public void say(){ // 可以访问外部类的所有成员 System.out.println("n1 = " + n1 + " name = " + name + " Outer08 n1 = " + Outer08.this.n1); } } public Inner08 getInner08Instance(){ return new Inner08(); } public void t1(){ Inner08 inner08 = new Inner08(); inner08.say(); System.out.println(inner08.sal); } }静态内部类在成员内部类的基础上,加上 static 修饰可以直接访问外部类的所有静态成员,包括私有的可以添加任意修饰符作用域:同其他的成员,为整个类体外部其他类访问静态内部类,见代码重名遵守就近原则,如果想访问外部类的成员,使用 外部类名.成员 去访问package com.bbedu.innerclass; public class StaticInnerClass01 { public static void main(String[] args) { Outer10 outer10 = new Outer10(); outer10.m10(); // 外部其他类访问静态内部类 // 方式1,直接通过类名访问 Outer10.Inner10 inner10 = new Outer10.Inner10(); inner10.say(); // 方式2,编写一个方法,返回静态内部类的对象实例 Outer10.Inner10 inner101 = outer10.getInner10(); inner101.say(); Outer10.Inner10 inner102 = Outer10.getInner10_(); inner102.say(); } } class Outer10 { public static String name = "张三"; private static void cry(){ System.out.println("Outer10 cry()"); } static class Inner10 { // 成员内部类 private String name = "Mary"; public void say() { // 可以访问外部类的所有静态成员 System.out.println(name); System.out.println(Outer10.name); cry(); } } public void m10(){ Inner10 inner10 = new Inner10(); inner10.say(); } public Inner10 getInner10(){ return new Inner10(); } public static Inner10 getInner10_(){ return new Inner10(); } }练习5 5总结面向对象(基础、中级、高级)到此结束~?我亦无他,惟手熟尔本章练习结果:注意 color 是静态变量9.0 red100.0 redpackage homework; public class Homework02 { public static void main(String[] args) { Frock frock = new Frock(); System.out.println(frock.getNextNum()); System.out.println(frock.getNextNum()); Frock frock1 = new Frock(); Frock frock2 = new Frock(); Frock frock3 = new Frock(); System.out.println(frock1.getSerialNumber()); System.out.println(frock2.getSerialNumber()); System.out.println(frock3.getSerialNumber()); } } class Frock { private static int currentNum = 100000; private int serialNumber; public int getNextNum(){ currentNum += 100; return currentNum; } public Frock() { serialNumber = getNextNum(); } public int getSerialNumber() { return serialNumber; } }package homework; public class Homework03 { public static void main(String[] args) { Animal cat = new Cat(); cat.shout(); Animal dog = new Dog(); dog.shout(); } } abstract class Animal { abstract void shout(); } class Cat extends Animal { @Override void shout() { System.out.println("猫会喵喵叫~"); } } class Dog extends Animal { @Override void shout() { System.out.println("狗会汪汪叫~"); } }package homework; public class Homework04 { public static void main(String[] args) { Cellphone cellphone = new Cellphone(); cellphone.testWork(new Cal() { @Override public double work(double n1, double n2) { return n1 + n2; } }, 10, 20); } } interface Cal { double work(double n1, double n2); } class Cellphone{ public void testWork(Cal iCal, double n1, double n2){ double work = iCal.work(n1, n2); System.out.println("result = " + work); } }package homework; public class Homework05 { public static void main(String[] args) { new A().test(); } } class A { private String name = "Bob"; public void test(){ class B{ private String name = "Tom"; public void show(){ System.out.println("Inner B class name=" + name + "\nA class name=" + A.this.name); } } B b = new B(); b.show(); } }领略程序结构:package homework; import javax.print.attribute.standard.JobHoldUntil; public class Homework06 { public static void main(String[] args) { Person monk = new Person("唐僧", new Boat()); monk.common(); monk.passRiver(); monk.passRiver(); monk.common(); monk.passFireHill(); } } interface Vehicles { void work(); } class Horse implements Vehicles { @Override public void work() { System.out.println("骑马中..."); } } class Boat implements Vehicles { @Override public void work() { System.out.println("开船中..."); } } class Plane implements Vehicles { @Override public void work() { System.out.println("开飞机..."); } } class TransportFactory { private static Horse horse = new Horse(); public static Boat getBoat() { Boat boat = new Boat(); return boat; } // 确保马始终是同一匹,饿汉式 public static Horse getHorse() { return horse; } public static Plane getPlane() { Plane plane = new Plane(); return plane; } } class Person { private String name; private Vehicles vehicles; public Person(String name, Vehicles vehicles) { this.name = name; this.vehicles = vehicles; } // 把具体的要求封装成方法 => 编程思想 public void passRiver(){ //先得到船 if(!(vehicles instanceof Boat)){ vehicles = TransportFactory.getBoat(); } vehicles.work(); } public void common() { // 判断一下当前的 vehicles 属性是否已经存在 if(!(vehicles instanceof Horse)){ vehicles = TransportFactory.getHorse(); // 向上转型 } vehicles.work(); } public void passFireHill(){ if(!(vehicles instanceof Plane)){ vehicles = TransportFactory.getPlane(); } vehicles.work(); } } package homework; public class Homework07 { public static void main(String[] args) { Car car = new Car(50.4); car.new Air().flow(); Car car1 = new Car(-10.0); car1.new Air().flow(); Car car2 = new Car(24); car2.new Air().flow(); } } class Car { private double temperature; public Car(double temperature) { this.temperature = temperature; } class Air { public void flow() { if (temperature > 40) { System.out.println("吹冷气"); } else if (temperature < 0) { System.out.println("吹暖气"); } else { System.out.println("关闭空调"); } } } }package homework; public class Homework08 { public static void main(String[] args) { // 演示 switch 使用 Color green = Color.GREEN; green.show(); switch (green) { case GREEN: System.out.println("匹配到绿色"); break; case RED: System.out.println("匹配到红色"); break; case BLUE: System.out.println("匹配到蓝色"); break; default: System.out.println("没有匹配到"); } } } interface IColor { void show(); } enum Color implements IColor{ RED(255,0,0), BLUE(0, 0,255), BLACK(0,0,0), YELLOW(255,255,0), GREEN(0,255,0); private int redValue; private int greenValue; private int blueValue; Color(int redValue, int greenValue, int blueValue) { this.redValue = redValue; this.greenValue = greenValue; this.blueValue = blueValue; } @Override public void show() { System.out.println("属性值为" + redValue + " " + greenValue + " " + blueValue); } }
2023年02月26日
45 阅读
0 评论
0 点赞
2023-02-26
Chapter09_房屋出租系统
源码见附件需求设计程序框架图(分层模式 => 当软件比较复杂,需要模式管理)系统又那些类(文件)明确类与类的调用关系HouseView.java [界面] 显示界面;接收用户的输入;调用 HouseService 类完成对房屋信息的各种操作HouseService.java [业务层] 响应 HouseView 的调用;完成对服务信息的各种操作(增删改查 C[create]R[read]U[update]D[delete])House.java [domain/model] 一个 House 对象表示一个房屋信息HouseRentApp.java [程序入口] 调用 HouseVies对象,调用该对象,显示主菜单Utility [工具类] 完成获取用户的各种输入实现准备工具类在实际开发中,公司会提供响应的工具类和开发库,可以提高开发效率,程序员也需要能够看懂别人写的代码,并且能够正确地调用菜单实现功能的三部曲:明确完成功能 -> 思路分析 -> 代码实现用户打开软件,可以看到主菜单,可以退出软件思路:在 HouseView.java 中,编写一个 mainMenu,显示菜单出租列表各司其职功能实现
2023年02月26日
57 阅读
0 评论
0 点赞
2023-02-26
Chapter08_OOP中级
面向对象编程(中级)IDEA 使用快捷键File -> Settings -> Keymap模板FIle -> Settings -> Editor -> Live Templates包包的作用区分相同名字的类当类很多时,包可以很好地管理类控制访问范围包的基本语法package com.hspedupackage 关键字,表示打包com.hspedu 表示包名包的本质分析(原理)包的本质就是创建不同的文件夹(目录)来保存类文件快速入门命名规则只能包含数字、字母、下划线、小圆点,但不能以数字开头,不能是关键字或保留字命名规范一般是小写字母 + 小圆点com.公司名.项目名.业务模块名常用的包java.lang.* // lang 包是基本包,默认引入的,不需要再引入java.util.* // util 包,系统提供的工具包,工具类,使用 Scannerjava.net.* // 网络包,网络并发java.awt.* // 做 java 界面开发,GUI细节我们引入一个包的主要目的是要使用该包下的类比如 import java.util.Scanner ,就只是引入一个类Scannerimport java.util.* ,表示将 java.util 包所有引入建议:需要使用哪个类就导入哪个类即可,不建议使用 * 导入package 的作用是声明当前类所在的包,需要放在类的最上面,一个类中最多有一句 packageimport 指令,放在 package 的下面,在类定义前面,可以有多句且没有顺序要求访问修饰符(modifier)基本介绍java 提供四种访问控制修饰符号,用于控制方法和属性(成员变量)的访问权限(范围):公开级别:用 public 修饰,对外公开受保护级别:用 protected 修饰,对子类和同一个包中的类公开默认级别:没有修饰符号,向同一个包的类公开私有级别:用 private 修饰,只有类本身可以访问,不对外公开细节修饰符可以用来修饰类中的属性、成员方法以及类只有默认修饰符和 public 才能修饰类子类后面再讨论成员方法的访问规则和属性完全一样*封装(encapsulation)封装是把抽象出的数据(属性)和对数据的操作(方法)封装在一起,数据被保护在内部,程序的其他部分只有通过授权的操作(方法),才能对数据进行操作。封装的好处隐藏实现细节 方法 <-- 调用可以对数据进行验证,保证安全合理实现步骤将属性私有化 private【不能直接修改属性】提供一个公共的 public set 方法,用于对属性判断并赋值public void setXxx(参数列表){ // 加入数据验证的业务逻辑 属性 = 参数名;}提供一个公共的 public get 方法,用于获取属性的值public 数据类型 getXxx(){ // 权限判断,Xxx 某个属性 return xx;}快速入门package com.bbedu.encap; public class Encapsulation01 { public static void main(String[] args) { Person person = new Person(); person.setName("Jack"); person.setAge(30); person.setSalary(30000); System.out.println(person.info()); Person tim = new Person("Tim", 2000, 20000); System.out.println("======Tim's information======\n" + tim.info()); } } class Person { public String name; // 名字公开 private int age; // 年龄私有化 private double salary; // 与构造器结合 public Person() { } public Person(String name, int age, double salary) { // this.name = name; // this.age = age; // this.salary = salary; // 我们可以将set方法写在构造器中,这样仍然可以验证 setName(name); setAge(age); setSalary(salary); } // 自动 set get, alt + insert public String getName() { return name; } public void setName(String name) { // 加入对数据的校验 if(name.length() >= 2 && name.length() <= 6){ this.name = name; }else{ System.out.println("名字长度有误,需要(2-6)字符,默认佚名"); this.name = "佚名"; } } public int getAge() { return age; } public void setAge(int age) { // 判断 if(age >= 1 && age <= 120){ this.age = age; }else{ System.out.println("年龄输入有误,要在1-120岁,默认为18"); this.age = 18; // 默认年龄 } } public double getSalary() { return salary; } public void setSalary(double salary) { // 可以增加当前对象的权限判断 this.salary = salary; } // 写一个方法,返回属性信息 public String info(){ return "信息为 name=" + name + " age=" + age + " salary=" + salary; } } 练习Account.javapackage com.bbedu.encap; public class Account { // 三个属性设为 private private String name; private double balance; private String pwd; // 提供两个构造器 public Account(){ } public Account(String name, double balance, String pwd) { this.setName(name); this.setBalance(balance); this.setPwd(pwd); } public String getName() { return name; } public void setName(String name) { if(name.length() >= 2 && name.length() <= 4){ this.name = name; }else{ System.out.println("姓名输入错误,应为(2-4位),默认为佚名"); this.name = "佚名"; } } public double getBalance() { return balance; } public void setBalance(double balance) { if(balance > 20){ this.balance = balance; }else{ System.out.println("余额必须(>20), 默认位0"); this.balance = 0; } } public String getPwd() { return pwd; } public void setPwd(String pwd) { if(pwd.length() == 6){ this.pwd = pwd; }else { System.out.println("密码必须是(6位), 默认为000000"); this.pwd = "000000"; } } //显示账号信息 public void showInfo() { System.out.println("账号信息 name="+ name + " 余额=" + balance + "" + " 密码=" + pwd); } } TestAccount.javapackage com.bbedu.encap; public class TestAccount { public static void main(String[] args) { // 创建Account Account account = new Account(); account.setName("Jack Chan"); account.setBalance(6); account.setPwd("222"); account.showInfo(); Account tim = new Account("Tim", 123, "233233"); tim.showInfo(); } }*继承基本介绍继承可以解决代码复用,让我们的编程更加靠近人类思维,当多个嘞存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过 extends 来声明继承父类即可基本语法class 子类 extends 父类{}子类会自动拥有父类定义的属性和方法父类又叫超类,基类子类又叫派生类快速入门package com.bbedu.extend_; // 父类,是 Pupil 和 Graduate 的父类 public class Student { // 共有属性 public String name; public int age; private double score; // 共有方法 public void setScore(double score) { this.score = score; } public void showInfo() { System.out.println("学生名 " + name + " 年龄 " + age + " 成绩 " + score); } } package com.bbedu.extend_; public class Pupil extends Student{ public void testing() { System.out.println("小学生" + name + "正在考小学数学.."); } } package com.bbedu.extend_; public class Graduate extends Student{ public void testing() { System.out.println("大学生 " + name + "正在考高等数学.."); } } package com.bbedu.extend_; public class Extends01 { public static void main(String[] args) { Pupil pupil = new Pupil(); pupil.name = "Lily"; pupil.age = 10; pupil.testing(); pupil.setScore(70); pupil.showInfo(); System.out.println("=========="); Graduate graduate = new Graduate(); graduate.name = "Kris"; graduate.age = 20; graduate.testing(); graduate.setScore(60); graduate.showInfo(); } } 细节子类继承所有的属性和方法,非私有的属性和方法可以在子类直接访问,但是私有属性不能直接在子类访问,要通过公共的方法去访问子类必须调用父类的构造器,完成父类的初始化当创建子类对象时,不管使用子类的哪个构造器,默认情况下总会调用父类的无参构造器;如果父类没有无参构造器,则必须在子类的构造器中用 super 去指定使用父类的哪个构造器去完成对父类的初始化工作,否则编译不会通过如果希望指定去调用父类的某个构造器,则需要显示地调用:super(参数列表)super 必须放在方法的第一行(super 只能在构造器中使用)super() 和 this() 都只能放在构造器第一行,因此这两个方法不能共存在一个构造器java 所有类都是 Object 类的子类,Object 是所有类的基类父类构造器的调用不限于直接父类,将一直往上追溯直到 Object 类(顶级父类)子类最多只能继承一个父类(指直接继承),即 java 中是单继承机制不能滥用继承,子类和父类之间必须要满足 is-a 的逻辑关系继承的本质package com.bbedu.extend_; /** * 继承的本质 */ public class ExtendsTheory { public static void main(String[] args) { Son son = new Son(); // 内存的布局 // 要按查找规则返回信息 // 首先看子类是否有该属性,如果有且能访问,则返回 // 如果子类没有这个信息,就看父类有没有这个属性,如果有且能访问,则访问 // 依次向上找 System.out.println(son.name); System.out.println(son.getFatherAge()); System.out.println(son.hobby); } } class GrandPa { String name = "大头爷爷"; String hobby = "旅游"; } class Father extends GrandPa { String name = "大头爸爸"; private int age = 39; public int getFatherAge() { return age; } } class Son extends Father { String name = "大头儿子"; } 练习会输出:a b name b正确会输出:我是A类 hahah我是B类的有参构造 我是c类的有参构造 我是c类的无参构造package com.bbedu.extend_.exercise; class PC extends Computer { private String brand; public PC(String cpu, String memory, String drive, String brand) { super(cpu, memory, drive); this.brand = brand; } public void printInfo(){ System.out.println(getDetails() + " brand=" + brand); } } package com.bbedu.extend_.exercise; class Computer { private String cpu; private String memory; private String drive; public Computer(String cpu, String memory, String drive) { this.cpu = cpu; this.memory = memory; this.drive = drive; } public String getDetails(){ return ("CPU型号:" + cpu + " 内存大小:" + memory + " 硬盘大小:" + drive); } } package com.bbedu.extend_.exercise; class NotePad extends Computer { private String color; public NotePad(String cpu, String memory, String drive, String color) { super(cpu, memory, drive); this.color = color; } public void printInfo(){ System.out.println(getDetails() + " color=" + color); } } package com.bbedu.extend_.exercise; public class ExtendsExercise03 { public static void main(String[] args) { PC pc = new PC("Apple", "16GB", "512GB", "Apple"); pc.printInfo(); NotePad notePad = new NotePad("Qualcomm", "6GB", "128GB", "Silver"); notePad.printInfo(); } } super 关键字基本介绍super 代表父类的引用,用于访问父类的属性、方法、构造器基本语法访问父类的属性,但不能访问父类的 private 属性访问父类的方法,不能访问父类的 private 方法访问父类的构造器:super(参数列表),只能放在构造器的第一句,且只能出现一句好处、细节调用父类的构造器的好处:分工明确,父类属性由父类初始化,子类的属性由子类初始化当子类中有和父类中的成员重名时,为了访问父类中的成员,则必须使用 super,若不重名,使用 super、 this 和 直接访问 效果相同super 的访问不限于直接父类,如果爷爷类和本类中有同名的成员,也可以使用 super 去访问爷爷类的成员,如果多个基类中都有相同名字的成员,使用 super 时遵循就近原则。A -> B -> Cpackage com.bbedu.super_; public class Base { public int n1 = 999; public int age = 111; public void cal(){ System.out.println("Base类的 cal() 方法"); } public void eat() { System.out.println("Base类的 eat() 方法"); } } package com.bbedu.super_; public class A extends Base { // 四个属性 // public int n1 = 100; protected int n2 = 200; int n3 = 300; private int n4 = 400; public A(){ } public A(String name){ } public A(String name, int age){ } // public void cal(){ // System.out.println("A类的 cal() 方法"); // } public void test100(){ } protected void test200(){ } void test300(){ } private void test400() { } } package com.bbedu.super_; public class B extends A { public int n1 = 888; // 访问父类的构造器:super(参数列表),只能放在构造器的第一句,且只能出现一句 public B() { // super(); // super("Jack"); super("Tim", 20); } public void cal() { System.out.println("B类的 cal() 方法"); } public void sum() { System.out.println("B类的 sum() 方法"); // 调用父类A的cal方法,有三种方法: // cal(): 先找本类,再向父类追溯 // 若找到但不能访问,则报错,若找不到,则提示不存在 cal(); // 等价于 cal() this.cal(); // 没有查找本类的过程,直接查找父类 super.cal(); // 访问属性的规则, n1 和 this.n1 相同 // 本类没有则查找父类 System.out.println(n1); System.out.println(this.n1); System.out.println(super.n1); System.out.println(age); eat(); } // 访问父类的属性,但不能访问父类的 private 属性 public void hi() { System.out.println(super.n1 + " " + super.n2 + " " + super.n3); } // 访问父类的方法,不能访问 private 方法 public void ok() { // super.test100(); // super.test200(); super.test300(); } } package com.bbedu.super_; public class super01 { public static void main(String[] args) { B b = new B(); b.sum(); } } super 和 this 的比较No.区别点thissuper1访问属性访问本类中的属性,如果本类没有则从父类继续查找从父类开始查找属性2调用方法访问本类中的方法,如果本类没有,则从父类继续查找从父类开始查找方法3调用构造器调用本类构造器,必须放在构造器的首行调用父类的构造器,必须放在子类构造器的首行4特殊表示当前对象子类中访问父类对象方法重写 / 覆盖(override)基本介绍方法重写就是子类有一个方法,和父类的某个方法的名称、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的方法细节子类的方法的参数,方法名称,要和父类方法一致子类方法的返回类型和父类返回方法一致,或是父类返回类型的子类子类方法不能缩小父类方法的访问权限练习名称发生范围方法名参数列表返回类型修饰符重载(overload)本类必须一样类型,个数或顺新至少有一个不同无要求无要求重写(override)父子类必须一样相同一致或子是父的子类子类不能缩小package com.bbedu.override_; public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String say(){ String s = "name = " + this.name + " age = " + this.age; return s; } } package com.bbedu.override_; public class Student extends Person{ private String id; private int score; public Student(String name, int age, String id, int score) { super(name, age); this.id = id; this.score = score; } @Override public String say() { return super.say() + " id = " + id + " score = " + score; } } package com.bbedu.override_; public class OverrideExercise { public static void main(String[] args) { Person jack = new Person("Jack", 35); System.out.println(jack.say()); Student student = new Student("Tim", 20, "123456", 100); System.out.println(student.say()); } } *多态(polymorphic)基本介绍方法或对象具有多种形态,是面向对象的第三大特征,多态是建立在封装和继承的基础之上的重写和重载就体现多态对象的多态(核心)(1) 一个对象的编译类型和运行类型可以不一致(2) 编译类型在定义对象时,就确定了,不能改变(3) 运行类型是可以变化的(4) 编译类型看定义时 = 的左边,运行类型看 = 的右边package com.bbedu.poly_.objectpoly_; public class Animal { public void cry(){ System.out.println("Animal 动物在叫..."); } } package com.bbedu.poly_.objectpoly_; public class Dog extends Animal { public void cry(){ System.out.println("Dog 小狗在叫..."); } } package com.bbedu.poly_.objectpoly_; public class Cat extends Animal { public void cry(){ System.out.println("Cat 小猫在叫..."); } } package com.bbedu.poly_.objectpoly_; public class PolyObject { public static void main(String[] args) { Animal animal = new Dog(); animal.cry(); animal = new Cat(); animal.cry(); } } 细节*多态的前提是:两个对象(类)存在继承关系多态的向上转型本质:父类的引用指向了子类的对象语法:父类类型 引用名 = new 子类类型();特点:编译类型看左边,运行类型看右边可以调用父类中的所有成员无法调用子类的特有成员,因为在编译阶段,能调用那些成员,是由编译类型来绝决定的最终的运行效果看子类的具体实现package com.bbedu.poly_.detail_; public class Animal { String name = "动物"; int age = 10; public void sleep(){ System.out.println("睡"); } public void run(){ System.out.println("跑"); } public void eat(){ System.out.println("吃"); } public void show(){ System.out.println("hello 你好"); } } package com.bbedu.poly_.detail_; public class Cat extends Animal{ public void eat(){ System.out.println("Cat 猫吃鱼"); } public void catchMouse(){ System.out.println("Cat 猫猫抓老鼠"); } }package com.bbedu.poly_.detail_; public class PolyDetail { public static void main(String[] args) { // 向上转型,父类的引用指向了子列的对象 Animal animal = new Cat(); Object object = new Cat(); // 可行 // (1)可以调用父类中的所有成员 // animal.catchMouse(); // 错误,(2)无法调用子类的特有成员 // (3)因为在编译阶段,能调用那些成员,是由编译类型来绝决定的 // (4)最终的运行效果看子类的具体实现 // 调用方法时,按照从子类开始查找方法,规则与前面的方法调用一致 animal.eat(); animal.run(); animal.show(); animal.sleep(); } }多态的向下转型语法:子类类型 引用名 = (子类类型) 父类引用;只能强转父类的引用,不能强转父类的对象要求父类的引用必须指向的是当前目标类型的对象当向下转型后,可以调用子类类型中的所有成员细节属性没有重写之说,属性的值看编译类型package com.bbedu.poly_.detail_; public class PolyDetail02 { public static void main(String[] args) { Sub sub = new Sub(); System.out.println(sub.count); Base base = new Sub(); System.out.println(base.count); } } class Base { int count = 10; } class Sub extends Base { int count = 20; }instanceof 比较操作符,用于判断对象 的运行类型是否为XX类型或XX类型的子类型package com.bbedu.poly_.detail_; public class PolyDetail03 { public static void main(String[] args) { BB bb = new BB(); System.out.println(bb instanceof BB); // true System.out.println(bb instanceof AA); // true // aa 编译类型 AA, 运行类型 BB AA aa = new BB(); System.out.println(aa instanceof AA); // true System.out.println(aa instanceof BB); // true Object obj = new Object(); System.out.println(obj instanceof AA); // false String str = "hello"; System.out.println(str instanceof Object); // true } } class AA { } class BB extends AA { } 练习package com.bbedu.poly_; public class PolyExercise02 { public static void main(String[] args) { Sub sub = new Sub(); System.out.println(sub.count); sub.display(); Base b = sub; System.out.println(sub == b); System.out.println(b.count); b.display(); } } 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); } }属性看编译,方法看运行java 的动态绑定机制 (重要)当调用对象方法时,该方法会和该对象的内存地址/运行类型 绑定当调用属性时,没有动态绑定机制,哪里声明,哪里使用package com.bbedu.poly_.danamic_; public class DynamicBinding { public static void main(String[] args) { A a = new B(); // 子类中有的话,为40 // 子类没有的话,getI()调用子类的,此为动态绑定,20+10,为30 System.out.println(a.sum()); // 属性没有动态绑定,10+10,为20 System.out.println(a.sum1()); } } class A{ public int i = 10; public int sum(){ return getI() + 10; } public int getI() { return i; } public int sum1() { return i + 10; } } class B extends A { public int i = 20; // public int sum() { // return i + 20; // } @Override public int getI() { return i; } // public int sum1() { // return i + 10; // } }多态数组数组的定义类型为父类类型,里面保存的实际元素类型为子类类型package com.bbedu.poly_.polyarr_; public class Person { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String say() { return "name = " + name + "\tage = " + age; } }package com.bbedu.poly_.polyarr_; public class Student extends Person { private double score; public Student(String name, int age, double score) { super(name, age); this.score = score; } public double getScore() { return score; } public void setScore(double score) { this.score = score; } @Override public String say() { return super.say() + "\tscore=" + score; } public void study() { System.out.println("学生 " + getName() + " 正在学习"); } }package com.bbedu.poly_.polyarr_; public class Teacher extends Person{ private double salary; public Teacher(String name, int age, double salary) { super(name, age); this.salary = salary; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } @Override public String say() { return super.say() + "\tsalary=" + salary; } public void teach() { System.out.println("老师 " + getName() + " 正在上课"); } }package com.bbedu.poly_.polyarr_; public class PolyArray { public static void main(String[] args) { // 1 Person、2 Student、1 Teacher Person[] persons = new Person[5]; persons[0] = new Person("Tim", 20); persons[1] = new Student("Sam", 20, 80); persons[2] = new Student("Amy", 30, 60); persons[3] = new Teacher("Rain", 50, 20000); persons[4] = new Teacher("Peter", 34, 14000); for (int i = 0; i < persons.length; i++) { // person[i] 的编译类型都为 Person,运行类型根据实际情况 System.out.println(persons[i].say()); // 判断运行类型,向下转型 if(persons[i] instanceof Student){ // Student s = (Student) persons[i]; // s.study(); ((Student) persons[i]).study(); } else if(persons[i] instanceof Teacher){ // Teacher t = (Teacher) persons[i]; // t.teach(); ((Teacher) persons[i]).teach(); } else { System.out.println("不是学生也不是老师"); } } } }多态参数package com.bbedu.poly_.polyparameter_; public class Employee { private String name; private double salary; public Employee(String name, double salary) { this.name = name; this.salary = salary; } public double getAnnual() { return 12 * salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } }package com.bbedu.poly_.polyparameter_; public class Worker extends Employee { public Worker(String name, double salary) { super(name, salary); } public void work(){ System.out.println("员工 " + getName() + " is working"); } @Override public double getAnnual() { // 直接调用父类方法 return super.getAnnual(); } }package com.bbedu.poly_.polyparameter_; public class Manager extends Employee { private double bonus; public Manager(String name, double salary, double bonus) { super(name, salary); this.bonus = bonus; } public double getBonus() { return bonus; } public void setBonus(double bonus) { this.bonus = bonus; } public void manage(){ System.out.println("经理 " + getName() + " is managing"); } @Override public double getAnnual() { return super.getAnnual() + bonus; } }package com.bbedu.poly_.polyparameter_; public class PolyParameter { public static void main(String[] args) { Worker tom = new Worker("Tom", 7000); Manager sam = new Manager("Sam", 10000, 30000); PolyParameter polyParameter = new PolyParameter(); polyParameter.showEmpAnnual(tom); polyParameter.showEmpAnnual(sam); polyParameter.testWork(tom); polyParameter.testWork(sam); } public void showEmpAnnual(Employee e) { System.out.println(e.getAnnual()); } public void testWork(Employee e){ // 向下转型 if(e instanceof Worker) { ((Worker) e).work(); }else if(e instanceof Manager){ ((Manager) e).manage(); }else { System.out.println("不做处理..."); } } }Object 类equals 方法== 和 equals 的对比== 是一个比较运算符既可以判断基本类型,又可以判断引用类型如果判断基本类型,判断的是 值 是否相等如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象euqals 方法euqals 是Object 类中的方法,只能判断引用类型默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等。比如 Integer, String练习package com.bbedu.object_; public class EuqalsExercise01 { public static void main(String[] args) { Person person = new Person("Tom", 10, '男'); Person person1 = new Person("Tom", 10, '男'); Person person2 = new Person("Jack", 20, '男'); System.out.println(person.equals(person1)); // 默认为false, Object 比较的是地址 System.out.println(person.equals(person2)); } } class Person { private String name; private int age; private char gender; @Override public boolean equals(Object obj) { // 如果比较的对象是同一个,则直接返回true if (this == obj){ // this 即为调用此方法的当前对象 return true; } if(obj instanceof Person){ //类型是Person才比较 Person p = (Person) obj; return this.name.equals(this.name) && this.age == p.age && this.gender == p.gender; // if (((Person) obj).age == this.age && // ((Person) obj).name.equals(this.name) && // ((Person) obj).gender == this.gender){ // return true; // } } return false; } public Person(String name, int age, char gender) { this.name = name; this.age = age; this.gender = gender; } 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 char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } } false/true/false/true/falsetrue/true/true/false/true/编译错误(不是同一种对象)字符的本质是整数hashCode返回该对象的哈希码值提高哈结构的容器的效率两个引用,如果指向的是同一个对象,则哈希值肯定是一样的两个引用,如果指向的是不同对象,则哈希值是不一样的哈希值主要是根据地址来计算的,但不能完全等价为地址示例后面的集合中再重写该方法package com.bbedu.object_; public class HashCode_ { public static void main(String[] args) { AA aa = new AA(); AA aa2 = new AA(); AA aa3 = aa; System.out.println("aa.hashCode()=" + aa.hashCode()); System.out.println("aa2.hashCode()=" + aa2.hashCode()); System.out.println("aa3.hashCode()=" + aa3.hashCode()); } } class AA { }toString返回该对象的字符串表示默认返回:全类型+@+哈希值的十六进制重写 toString 方法,打印对象或拼接对象式,都会自动调用该对象的 toString 形式当直接输出一个对象时,toString 方法就会默认调用该对象的 toString 方法package com.bbedu.object_; public class ToString_ { public static void main(String[] args) { /* jdk 源码 public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } */ Monster monster = new Monster("妖怪", "巡山", 2000); System.out.println(monster.toString()); System.out.println(monster.hashCode() + " HEX: " + Integer.toHexString(monster.hashCode())); // 直接输出一个对象时,toString 方法就会默认调用该对象的 toString 方法 System.out.println(monster); } } class Monster { private String name; private String job; private double sal; // 重写输出对象的属性 @Override public String toString() { // 一般是输出对象的属性 return "Monster{" + "name='" + name + '\'' + ", job='" + job + '\'' + ", sal=" + sal + '}'; } public Monster(String name, String job, double sal) { this.name = name; this.job = job; this.sal = sal; } }finalize (废弃)当对象被回收时,系统自动会调用该对象的 finalize 方法,子类可以重写该方法,做一些释放资源的操作什么时候被回收:当某个对象没有任何引用时,则 jvm 就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁该对象前,会调用 finalize() 方法断点调试 (debug)需求断点调试可以一步一步的看源码执行的过程,从而发现错误所在在断点调试过程中,是运行状态,是以对象的运行类型来执行的介绍断点调试是指在程序的某一行设置一个断点,调试时,程序运行到这一行就会停住,然后你可以一步一步往下调试,调试过程中可以看各个变量当前的值,出错的话,调试到出错的代码行即显示错误,停下。进行分析从而找到这个Bug断点调试是程序员必须掌握的技能。断点调试也能帮助我们查看java底层源代码的执行过程;提高程序员的Java水平。快捷键F7 跳入 F8 跳过、逐行执行 shift + F8 跳出 F9 resume, 执行到下一个断点案例1.package com.bbedu.debug_; public class Debug01 { public static void main(String[] args) { // 演示逐行执行 int sum = 0; for (int i = 0; i < 5; i++) { sum += i; System.out.println("i=" + i); System.out.println("sum=" + sum); } System.out.println("退出for..."); } }2.package com.bbedu.debug_; public class Debug02 { public static void main(String[] args) { int[] arr = {1, 10, -1}; for (int i = 0; i <= arr.length; i++) { System.out.println(arr[i]); } System.out.println("退出for..."); } }强制进入,查看源码package com.bbedu.debug_; import java.util.Arrays; public class Debug03 { public static void main(String[] args) { int[] arr = {8, -1, 10, 98, 45}; Arrays.sort(arr); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + "\t"); } } }resume, 动态下断点package com.bbedu.debug_; import java.util.Arrays; public class Debug04 { public static void main(String[] args) { int[] arr = {8, -1, 10, 98, 45}; Arrays.sort(arr); for (int i = 0; i < arr.length; i++) { System.out.print(arr[i] + "\t"); } System.out.println("Hello100"); System.out.println("Hello200"); System.out.println("Hello300"); System.out.println("Hello400"); System.out.println("Hello500"); System.out.println("Hello600"); } }jdk 源码也可下断点调试,不能到的会有下图显示:练习项目实战-零钱通化繁为简先完成显示菜单,并且可以选择,给出对应的提示信息完成零钱通明细完成收益入账消费退出,确认退出判断入账和消费金额是否合理将面向过程的代码改为面向对象的面向过程版本:package com.bbedu.smallchange; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner; import static java.lang.Thread.sleep; public class SmallChangeSys { public static void main(String[] args) throws InterruptedException { // 定义相关变量 boolean loop = true; Scanner scanner = new Scanner(System.in); String key = ""; String details = "\n------------------零钱通明细------------------"; double money = 0; double balance = 0; Date date = null; // Date 是 java.util.Date 类型,表示日期 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String note = null; String confirm = null; do { System.out.println("\n------------------零钱通菜单------------------"); System.out.println("\t\t\t1 零钱通明细"); System.out.println("\t\t\t2 收 益 入 账"); System.out.println("\t\t\t3 消 费"); System.out.println("\t\t\t4 退 出"); System.out.print("请选择(1-4):"); key = scanner.next(); switch (key){ case "1": System.out.println(details); break; case "2": System.out.print("收益入账金额:"); money = scanner.nextDouble(); // money 应该校验 // 不合理的直接退出 if (money <= 0) { System.out.println("! 收益入账金额需要大于0"); break; } balance += money; date = new Date(); // 日期格式化 details += "\n收益入账\t" + "+¥" + money + "\t" + sdf.format(date) + " 余额:" + balance; break; case "3": System.out.println("消费金额:"); money = scanner.nextDouble(); // 校验 if ( money <= 0 || money > balance){ System.out.println("! 消费金额应在 (0-"+balance+")"); break; } System.out.println("消费说明:"); note = scanner.next(); balance -= money; date = new Date(); details += "\n" + note + "\t-¥" + money + "\t" + sdf.format(date) + "\t余额:" + balance; break; case "4": // 编程遵守原子性 while (true){ System.out.println("确定要退出吗? (y/n)"); confirm = scanner.next(); if(confirm.equals("y") || confirm.equals("n")){ break; }else { System.out.println("! 输入有误, 请重新输入"); } } if (confirm.equals("y")){ System.out.print(" 退 出 中"); for (int i = 0; i < 3; i++) { Thread.sleep(300); System.out.print(" ."); } System.out.println(); loop = false; } break; default: System.out.println("! 选择有误,请重新选择"); } }while (loop); System.out.println("-----零钱通已退出-----"); } }面向对象版本:package com.bbedu.smallchange.oop; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Scanner; /** * 该类完成零钱通的各个功能 * 使用OOP * 将各个功能对应应该方法 */ public class SmallChangeSysOOP { // 定义相关变量 boolean loop = true; Scanner scanner = new Scanner(System.in); String key = ""; String details = "\n------------------零钱通明细------------------"; double money = 0; double balance = 0; Date date = null; // Date 是 java.util.Date 类型,表示日期 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm"); String note = null; String confirm = null; public void showTab(){ do { System.out.println("\n------------------零钱通选择菜单------------------"); System.out.println("\t\t\t1 零钱通明细"); System.out.println("\t\t\t2 收 益 入 账"); System.out.println("\t\t\t3 消 费"); System.out.println("\t\t\t4 退 出"); System.out.print("请选择(1-4):"); key = scanner.next(); switch (key){ case "1": detail(); break; case "2": income(); break; case "3": pay(); break; case "4": exit(); break; default: System.out.println("! 选择有误,请重新选择"); } }while (loop); } public void detail(){ System.out.println(details); } public void income(){ System.out.print("收益入账金额:"); money = scanner.nextDouble(); // money 应该校验 // 不合理的直接退出 if (money <= 0) { System.out.println("! 收益入账金额需要大于0"); return; // 退出方法,不在执行后面的代码 } balance += money; date = new Date(); // 日期格式化 details += "\n收益入账\t" + "+" + money + "\t" + sdf.format(date) + " 余额:" + balance; } public void pay(){ System.out.println("消费金额:"); money = scanner.nextDouble(); // 校验 if ( money <= 0 || money > balance){ System.out.println("! 消费金额应在 (0-"+balance+")"); return; } System.out.println("消费说明:"); note = scanner.next(); balance -= money; date = new Date(); details += "\n" + note + "\t-" + money + "\t" + sdf.format(date) + "\t余额:" + balance; } public void exit() { // 编程遵守原子性 while (true){ System.out.println("确定要退出吗? (y/n)"); confirm = scanner.next(); if(confirm.equals("y") || confirm.equals("n")){ break; }else { System.out.println("! 输入有误, 请重新输入"); } } if (confirm.equals("y")){ System.out.println(" 退 出 中"); loop = false; } System.out.println("-----零钱通已退出-----"); } }package com.bbedu.smallchange.oop; public class SmallChangeSysApp { public static void main(String[] args) { SmallChangeSysOOP smallChangeSysOOP = new SmallChangeSysOOP(); smallChangeSysOOP.showTab(); } }本章练习package com.bbedu.homework; public class Homework01 { public static void main(String[] args) { // 对象数组,注意声明方式: Person[] people = new Person[3]; people[0] = new Person("Jack", 30, "Coder"); people[1] = new Person("Tim", 20, "teacher"); people[2] = new Person("Mary", 40, "seller"); for (int i = 0; i < people.length; i++) { System.out.println(people[i]); } // 冒泡排序 for (int i = 0; i < people.length - 1; i++) { for (int j = 0; j < people.length - i -1; j++) { if (people[j].getAge() < people[j+1].getAge()){ int tmp = people[j].getAge(); people[j].setAge(people[j+1].getAge()); people[j+1].setAge(tmp); } } } System.out.println("===排序后==="); for (int i = 0; i < people.length; i++) { System.out.println(people[i]); } } } class Person{ private String name; private int age; private String job; public Person(String name, int age, String job) { this.name = name; this.age = age; this.job = job; } 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 String getJob() { return job; } public void setJob(String job) { this.job = job; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", job='" + job + '\'' + '}'; } }package com.bbedu.homework; public class Homework03 { public static void main(String[] args) { Professor professor = new Professor("Cook", 50, "CEO", 1500000, 1.3); professor.introduce(); } } class Teacher{ private String name; private int age; private String post; private double salary; private double grade; public Teacher(String name, int age, String post, double salary, double grade) { this.name = name; this.age = age; this.post = post; this.salary = salary; this.grade = grade; } 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 String getPost() { return post; } public void setPost(String post) { this.post = post; } public double getSalary() { return salary; } public void setSalary(double salary) { this.salary = salary; } public double getGrade() { return grade; } public void setGrade(double grade) { this.grade = grade; } public void introduce(){ System.out.print("name=" + name + " age=" + age + " post=" + post + " salary=" + salary); } } class Professor extends Teacher{ public Professor(String name, int age, String post, double salary, double grade) { super(name, age, post, salary, grade); } @Override public void introduce() { super.introduce(); System.out.println(" grade=" + this.getGrade()); } }package com.bbedu.homework; public class Homework04 { public static void main(String[] args) { Worker tim = new Worker("Tim", 100, 30); tim.printSalary(); Manager cook = new Manager("Cook", 300, 20); cook.printSalary(); } } class Employee { private String name; private double dayPay; private int workDay; public Employee(String name, double dayPay, int workDay) { this.name = name; this.dayPay = dayPay; this.workDay = workDay; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getDayPay() { return dayPay; } public void setDayPay(double dayPay) { this.dayPay = dayPay; } public int getWorkDay() { return workDay; } public void setWorkDay(int workDay) { this.workDay = workDay; } public void printSalary(){ System.out.print("name=" + name + " dayPay=" + dayPay + "workDay="+ workDay); } } class Worker extends Employee{ public Worker(String name, double dayPay, int workDay) { super(name, dayPay, workDay); } @Override public void printSalary() { System.out.print("Worker "); super.printSalary(); System.out.println(" salary=" + getWorkDay()*getDayPay()*1.0); } } class Manager extends Employee{ public Manager(String name, double dayPay, int workDay) { super(name, dayPay, workDay); } @Override public void printSalary() { System.out.print("Manager "); super.printSalary(); System.out.println(" salary=" + getWorkDay()*getDayPay()*1.2); } }package com.bbedu.homework.homework5; public class Test { public static void main(String[] args) { Employee[] e = new Employee[5]; e[0] = new Worker("Sam", 100); e[1] = new Waiter("Peter", 120); e[2] = new Peasant("Tony", 80); e[3] = new Teacher("Mary", 150, 20); e[4] = new Scientist("Bob", 200, 100000); for (int i = 0; i < e.length; i++) { e[i].printSal(); } } }package com.bbedu.homework.homework5; public class Employee { private String name; private double sal; public Employee(String name, double sal) { this.name = name; this.sal = sal; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } public void printSal(){ System.out.println("name=" + name + " salary=" + sal*365); } }package com.bbedu.homework.homework5; public class Worker extends Employee { public Worker(String name, double sal) { super(name, sal); } @Override public void printSal() { System.out.print("Worker "); super.printSal(); } }package com.bbedu.homework.homework5; public class Peasant extends Employee { public Peasant(String name, double sal) { super(name, sal); } @Override public void printSal() { System.out.print("Peasant "); super.printSal(); } }package com.bbedu.homework.homework5; public class Teacher extends Employee { private double dayPay; public Teacher(String name, double sal, double dayPay) { super(name, sal); this.dayPay = dayPay; } public double getDayPay() { return dayPay; } public void setDayPay(double dayPay) { this.dayPay = dayPay; } @Override public void printSal() { System.out.print("Teacher "); System.out.println("name=" + getName() + " salary=" + (getSal()+getDayPay())*365); } }package com.bbedu.homework.homework5; public class Scientist extends Employee{ private double bonus; public Scientist(String name, double sal, double bonus) { super(name, sal); this.bonus = bonus; } public double getBonus() { return bonus; } public void setBonus(double bonus) { this.bonus = bonus; } @Override public void printSal() { System.out.print("Scientist "); System.out.println("name=" + getName() + " salary=" + (getSal()*365+getBonus())); } }package com.bbedu.homework.homework5; public class Waiter extends Employee{ public Waiter(String name, double sal) { super(name, sal); } @Override public void printSal() { System.out.print("Waiter "); super.printSal(); } }package com.bbedu.homework.homework8; public class BankAccount { private double balance; public BankAccount(double initialBalance) { this.balance = initialBalance; } public void deposit(double amount) { balance += amount; } public void withdraw(double amount) { balance -= amount; } public double getBalance() { return balance; } }package com.bbedu.homework.homework8; public class CheckingAccount extends BankAccount { public CheckingAccount(double initialBalance) { super(initialBalance); } @Override public void deposit(double amount) { super.deposit(amount - 1); } @Override public void withdraw(double amount) { super.withdraw(amount + 1); } }package com.bbedu.homework.homework8; public class SavingAccount extends BankAccount{ private int freeCount = 3; private double rate = 0.01; // 利率 public SavingAccount(double initialBalance) { super(initialBalance); } public int getFreeCount() { return freeCount; } public void setFreeCount(int freeCount) { this.freeCount = freeCount; } public double getRate() { return rate; } public void setRate(double rate) { this.rate = rate; } @Override public void deposit(double amount) { if (freeCount > 0){ super.deposit(amount); } else { super.deposit(amount - 1); } freeCount--; } @Override public void withdraw(double amount) { if (freeCount > 0){ super.withdraw(amount); } else { super.withdraw(amount + 1); } freeCount--; } public void earnMonthlyInterest(){ freeCount = 3; super.deposit(getBalance()*rate); } }package com.bbedu.homework.homework8; public class Homework08 { public static void main(String[] args) { // CheckingAccount checkingAccount = new CheckingAccount(1000); // checkingAccount.deposit(100); // checkingAccount.withdraw(10); // System.out.println(checkingAccount.getBalance()); SavingAccount savingAccount = new SavingAccount(1000); savingAccount.deposit(100); savingAccount.deposit(100); savingAccount.deposit(100); System.out.println(savingAccount.getBalance()); savingAccount.deposit(100); System.out.println(savingAccount.getBalance()); savingAccount.earnMonthlyInterest(); savingAccount.deposit(100); System.out.println(savingAccount.getBalance()); } }public LabeledPoint(String label, double x, double y) { super(x, y); this.label = label; }package com.bbedu.homework.homework10; public class Doctor { private String name; private int age; private String job; private String gender; private double sal; public Doctor(String name, int age, String job, String gender, double sal) { this.name = name; this.age = age; this.job = job; this.gender = gender; this.sal = sal; } 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 String getJob() { return job; } public void setJob(String job) { this.job = job; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public double getSal() { return sal; } public void setSal(double sal) { this.sal = sal; } @Override public boolean equals(Object obj) { if(this == obj){ return true; } if(!(obj instanceof Doctor)){ return false; } Doctor doctor = (Doctor) obj; return doctor.age == this.age && doctor.sal == this.sal && doctor.name.equals(this.name) && doctor.job.equals((this.job)) && doctor.gender.equals(this.gender); } }package com.bbedu.homework.homework11; import java.rmi.StubNotFoundException; public class Homework11 { public static void main(String[] args) { // 向上转型 Person p = new Student(); // 可以用 Person 的 eat()和 run() 方法, 但run方法被Student类重写 // 不能调用子类的特有方法, 因为编译类型为父类 p.eat(); p.run(); // 向下转型 Student s = (Student) p; // 可以调用子类的所有方法 s.run(); s.eat(); s.study(); } }
2023年02月26日
48 阅读
0 评论
0 点赞
2022-09-20
Chapter 07 OOP初级 part3
本章练习以下代码均已编译通过public class Homework01 { public static void main(String[] args) { double[] arr = {2.45, 45.4, -4324.4, 434.7, 2.76}; A01 m = new A01(); Double ret = m.max(arr); if(ret != null){ System.out.println("最大值为:"+ret); }else{ System.out.println("Wrong input!"); } } } //完成基本功能后,再考虑健壮性 class A01{ // 包装类 Double public Double max(double[] arr){ // 先判不为空,再判长度大于零 if(arr != null && arr.length > 0){ double max = arr[0]; // 假定第一个数就是最大 for (int i = 1; i < arr.length; i++) { if(arr[i] > max){ max = arr[i]; } } return max; }else{ return null; } } } public class Homework02 { public static void main(String[] args) { A02 p = new A02(); String[] arr = {"Tim", "Jack", "Mary"}; System.out.println(p.find(arr, "Jack")); System.out.println(p.find(arr, "Java")); } } class A02 { public int find(String[] arr, String partten){ if(arr != null && arr.length > 0){ for(int i = 0; i < arr.length; i++){ if(partten.equals(arr[i])){ return i; } } } return -1; } } public class Homework03 { public static void main(String[] args) { Book b1 = new Book("三体", 120.99); b1.info(); b1.updatePrice(); b1.info(); } } class Book { String name; double price; public Book(String name, double price){ this.name = name; this.price = price; } public void updatePrice(){ if(this.price > 150){ this.price = 150; }else if(this.price > 100){ this.price = 100; } } public void info(){ System.out.println(this.name + "的价格为:" + this.price); } } public class Homework04 { public static void main(String[] args) { int[] arr = {1, 4, 6, 2, 3}; A03 a = new A03(); int[] newArr = a.copyArr(arr); for (int i = 0; i < newArr.length; i++) { System.out.print(newArr[i] + "\t"); } } } class A03 { public int[] copyArr(int[] oldArr){ // 在堆中创建一个长度为 oldArr.length 的数组 int[] newArr = new int[oldArr.length]; for(int i = 0; i < oldArr.length; i++){ newArr[i] = oldArr[i]; } return newArr; } } public class Homework05 { public static void main(String[] args) { Circle circle = new Circle(3); System.out.printf("周长为:%.2f\n", circle.perimeter()); System.out.printf("面积为:%.2f", circle.area()); } } class Circle { double radius; public Circle(double radius){ this.radius = radius; } // 周长 public double perimeter(){ return 2.0 * this.radius * Math.PI; } // 面积 public double area(){ return Math.PI * this.radius * this.radius; } } public class Homework06 { public static void main(String[] args) { Cale cale = new Cale(20, 4); System.out.println(cale.add()); System.out.println(cale.sub()); System.out.println(cale.mul()); if(cale.div() != null){ System.out.println(cale.div()); } Cale cale1 = new Cale(20, 0); if(cale1.div() != null){ System.out.println(cale1.div()); } } } class Cale { double op1, op2; public Cale(double op1, double op2){ this.op1 = op1; this.op2 = op2; } double add(){ return op1 + op2; } double sub(){ return op1 - op2; } double mul(){ return op1 * op2; } Double div(){ if(op2 == 0){ System.out.println("除数不能为零"); return null; }else{ return op1 / op2; } } } public class Homework07 { public static void main(String[] args) { Dog dog = new Dog("大黄", "White", 4); dog.show(); } } class Dog { String name; String color; int age; 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 + " 颜色=" + this.color+ " 年龄=" + this.age); } } public class Homework07 { public static void main(String[] args) { Dog dog = new Dog("大黄", "White", 4); dog.show(); } } class Dog { String name; String color; int age; 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 + " 颜色=" + this.color+ " 年龄=" + this.age); } } 9.略10.输出为:i=101j=100101101public double method(double n1, double n2){...}public class Homework12 { public static void main(String[] args) { Emploee emploee = new Emploee("Tim", "male", 20); System.out.println(emploee.name + "\t" + emploee.gender + "\t" + emploee.age); } } class Emploee { String name; String gender; int age; String position; int salary; public Emploee(String position, int salary){ this.position = position; this.salary = salary; } public Emploee(String name, String gender, int age){ this.name = name; this.gender = gender; this.age = age; } public Emploee(String name, String gender, int age, String position, int salary) { this(name, gender, age); // 复用第二个构造器,注意不能同时复用前两个 this.position = position; this.salary = salary; } } public class Homework13 { public static void main(String[] args) { new PassObject().printAreas(5); } } class Circle { double radius; public Circle(double radius){ this.radius = radius; } public double findArea(){ return radius * radius * Math.PI; } } class PassObject { public void printAreas(int times){ System.out.println("Radius" + "\t" + "Area"); for(double i = 1.0; i <= times; i++){ System.out.print(i + "\t"); System.out.print(new Circle(i).findArea()); System.out.println(); } } } import java.util.Random; import java.util.Scanner; import javax.lang.model.util.ElementScanner6; public class Homework14 { public static void main(String[] args) { // 创建扫描器接收数据 Scanner scanner = new Scanner(System.in); Tom tom = new Tom(); System.out.println("输入你想玩的局数:"); int countTotal = scanner.nextInt(); // 循环 countToatal 次 for(int i = 1; i <= countTotal; i++){ System.out.println("请出拳: 0-拳头 1-石头 2-剪刀 "); tom.tomGuessNum = scanner.nextInt(); tom.setTomGuessNum(tom.tomGuessNum); tom.comGuessNum = tom.computerNum(); String outcome = tom.vsComputer(); tom.winCountNum = tom.winCount(outcome); tom.showInfo(i, outcome); } System.out.println("你总共赢了:" + tom.winCountNum + "局"); scanner.close(); } } class Tom{ int tomGuessNum; int comGuessNum; int winCountNum; // 显示当前局信息 public void showInfo(int count, String outcome){ System.out.println("=================================================================="); System.out.println("当前局数\t你的出拳\t电脑出拳\t结果"); System.out.println(count + "\t\t" + tomGuessNum + "\t\t" + comGuessNum + "\t\t" + outcome); System.out.println("=================================================================="); } public int computerNum(){ Random r = new Random(); return r.nextInt(3); // 0-2的随机数 } public void setTomGuessNum(int tomGuessNum){ if(tomGuessNum > 2 || tomGuessNum < 0){ throw new IllegalArgumentException("输入有误"); } this.tomGuessNum = tomGuessNum; } public int getTomGuessNum(){ return tomGuessNum; } public String vsComputer(){ if(tomGuessNum == 0 && comGuessNum ==1 || tomGuessNum ==1 && comGuessNum == 2 || tomGuessNum == 2 && comGuessNum == 0){ return "你赢了"; }else if(tomGuessNum == comGuessNum){ return "平局"; }else{ return "你输了"; } } public int winCount(String s){ if(s.equals("你赢了")){ winCountNum++; } return winCountNum; } }
2022年09月20日
63 阅读
0 评论
0 点赞
2022-09-19
Chapter 07 OOP初级 part2
方法重载(OverLoad)java 中允许同一个类中,多个同名方法的存在,但要求形参列表不同比如: System.out.println(); out 是 PrintStream 类型好处:减轻起名的麻烦减轻记名的麻烦快速入门public class OverLoad01 { public static void main(String[] args) { MyCaculator c = new MyCaculator(); System.out.println(c.calculate(1, 2)); System.out.println(c.calculate(1, 2.5)); System.out.println(c.calculate(1.5, 2)); System.out.println(c.calculate(1, 2, 3)); } } class MyCaculator { public int calculate(int n1, int n2){ return n1 + n2; } public double calculate(int n1, double n2){ return n1 + n2; } public double calculate(double n1, int n2){ return n1 + n2; } public int calculate(int n1, int n2, int n3){ return n1 + n2 + n3; } }细节方法名要相同形参列表:必须不同(形参类型或个数或顺序,至少有一个不同,形参名无要求)返回类型无要求可变参数java 允许将同一个类中多个同名同功能但参数个数不同的方法,封装成一个方法。细节可变参数的实参可以为 0 个或任意多个可变参数的实参可以为数组可变参数的本质就是数组可变参数可以和普通类型的参数一起放在形参列表,但必须保证可变参数在最后一个形参列表中只能出现一个可变参数练习public class VarParameterExercise { public static void main(String[] args) { HspMethod method = new HspMethod(); System.out.println(method.showScore("bbchen", 100, 80)); // 2门 System.out.println(method.showScore("Tim", 90, 100, 80)); // 3门 System.out.println(method.showScore("Eason", 90, 100, 80, 70.5, 100)); //5门 } } class HspMethod { // 传入可变参数 scores public String showScore(String name, double... scores){ double totalScore = 0; for(int i = 0; i < scores.length; i++){ totalScore += scores[i]; // 当作数组处理求和 } String ret = name + " " + scores.length + "门课的总分为:" + totalScore; return ret; } }作用域 (scope)在 java 编程中,主要的变量就是属性(成员变量)和局部变量局部变量一般是指在成员方法中定义的变量作用域分类:全局变量:也就是属性局部变量:除了属性之外的其他变量,作用域为定义它的代码块中全局变量(属性)可以不赋值,直接使用,因为有默认值;局部变量必须赋值后才能使用,因为有默认值细节属性和局部变量可以重名,访问时遵循就近原则在同一个作用域中,比如同一个成员方法中,两个局部变量不能重名属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而销毁。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。即在一次方法调用过程中。作用域范围不同全局变量(属性):可以被本类使用,或者被其他类使用(通过对象调用)。两种调用方法:局部变量:只能在本类的对应方法中使用修饰符不同全局变量(属性)可以加修饰符(public protected private..)局部变量不可以加修饰符构造方法/构造器(constructor)构造方法又称构造器,是类的一种特殊方法,它的主要作用是完成对象的初始化。基本语法[修饰符] 方法名(形参列表){ 方法体;}说明:构造器的修饰符可以默认,也可以是 public protected private构造器没有返回值方法名和类名必须一样参数列表 和 成员方法一样的规则构造器的调用由系统完成快速入门public class Constructor01 { public static void main(String[] args) { // new一个对象时,直接通过构造器指定名字和年龄 Person p1 = new Person("Smith", 45); 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.构造器形参列表的规则和成员方法一致 public Person(String pName, int pAge){ System.out.println("构造器被调用,完成对象的属性初始化"); name = pName; age = pAge; } }细节一个类可以定义多个不同的构造器,即构造器重载构造器名和类名要相同构造器没有返回值构造器是完成对象的初始化,不是创建对象在创建对象时,系统自动调用该类的构造方法public class ConstructorDetail { public static void main(String[] args) { // new一个对象时,直接通过构造器指定名字和年龄 Person p1 = new Person("Smith", 45); // 第一个构造器 System.out.println("p1对象的name=" + p1.name); System.out.println("p1对象的age=" + p1.age); Person p2 = new Person("Jim"); // 第二个构造器 System.out.println("p2对象的name=" + p2.name); } } class Person{ String name; int age; // 第一个构造器 public Person(String pName, int pAge){ name = pName; age = pAge; } // 第二个构造器,只初始化姓名 public Person(String pName){ name = pName; } }如果程序员没有定义构造器,系统会自动给类生成一个默认无参构造器(也叫做默认构造器),使用 javap 指令反编译查看一旦定义了自己的构造器,默认的构造器就被覆盖了,就不能再使用默认的无参构造器,除非显式地定义一下:Dog(){}对象创建的流程分析对象(在堆中)数据先进行默认初始化,再进行显性初始化,最后构造器的初始化加载Person类信息(Person.class),只会加载一次在堆中分配空间(地址)完成对象初始化 =》三步对象在堆中的地址,返回给p(p是对象名,即对象的引用)public class ConstructorExercise { public static void main(String[] args) { // new一个对象时,直接通过构造器指定名字和年龄 Person p1 = new Person(); // 第一个构造器 System.out.println("p2对象的name=" + p1.name); // null // 构造器初始化总是最后执行,因此 p1.name 并非80而是18 System.out.println("p1对象的age=" + p1.age); // 18 Person p2 = new Person("Jim", 17); // 第二个构造器 System.out.println("p2对象的name=" + p2.name); System.out.println("p2对象age=" + p2.age); } } class Person{ // 第一个构造器,无参 public Person(){ age = 18; } // 第二个构造器,初始化 name 和 age public Person(String pName, int pAge){ name = pName; age = pAge; } String name; int age = 80; }this 关键字引出java 虚拟机会给每个对象分配 this,代表当前对象。使用 this 解决上图的变量命名问题。public Dog(String name, int age){ // this.name 就是当前对象的属性 name this.name = name; // this.age 就是当前对象的属性 age this.age = age; }理解 this简单的说,哪个对象调用,this 就代表哪个对象细节this 可以用来访问本类的属性、方法、构造器this 用于区分当前类的属性和局部变量访问成员方法的语法:this.方法名(参数列表)访问构造器语法:this(参数列表);注意只能在构造器中使用(即只能在构造器中访问另一个构造器)注意this(参数列表)必须放置在第一条语句this 不能在类定义的外部使用,只能在类定义的方法中使用public class This01 { public static void main(String[] args) { Person p1 = new Person("Tim", 18); Person p2 = new Person("Smith", 20); Person p3 = new Person("Tim", 18); System.out.println("p1 p2比较结果:" + p1.compareTo(p2)); System.out.println("p1 p3比较结果:" + p1.compareTo(p3)); } } class Person{ String name; int age; // 构造器 public Person(String name, int age){ this.name = name; this.age = age; } public boolean compareTo(Person p){ // 姓名年龄是否一样 // if(this.name.equals(p.name) && this.age == p.age){ // return true; // } // else{ // return false; // } return this.name.equals(p.name) && this.age == p.age; } }
2022年09月19日
47 阅读
1 评论
0 点赞
1
...
4
5
6
7