当前位置: 首页 > news >正文

java学习笔记6

按住shift键,选择开始的一位和最后结束的一位来全选

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

面向对象特征之二:继承性1.继承性的理解
> 生活上:财产的继承、颜值的继承
> 代码层面:> 自上而下:定义了一个类A,在定义另一个类B时,发现类B的功能与类A相似,考虑类B继承于类A> 自下而上:定义了类B,C,D等,发现B、C、D有类似的属性和方法,则可以考虑将相同的属性和方法进行抽取,封装到类A中,让类B、C、D继承于类A,同时,B、C、D中的相似的功能就可以删除了。
2.继承性的好处
- 继承的出现减少了代码冗余,提高了代码的复用性。
- 继承的出现,更有利于功能的扩展。
- 继承的出现让类与类之间产生了'is-a'的关系,为多态的使用提供了前提。- 继承描述事物之间的所属关系,这种关系是:'is-a’的关系。可见,父类更通用、更一般,子类更具体。3.继承的格式:
class A{//属性、方法
}class B extends A {}
继承中的基本概念:
类A:父类、superclass、超类、基类
类B:子类、subClass、派生类4.有了继承性以后:
> 子类就获取到了父类中声明的所有的属性和方法。
> 但是,由于封装性的影响,可能子类不能直接调用父类中声明的属性或方法。
> 子类在继承父类以后,还可以扩展自己特有的功能(体现:增加特有的属性、方法)extends:延展,扩展,延伸子类和父类的理解,要区别于集合和子集
>不要为了继承而继承。在继承之前,判断一下是否有is a的关系。5.默认的父类:
Java中声明的类,如果没有显式的声明其父类时,则默认继承于java.lang.0bject6.补充说明:
> Java是支持多层继承。
> 概念:直接父类、间接父类
> Java中的子父类的概念是相对的。
Java中一个父类可以声明多个子类。反之,一个子类只能有一个父类(Java的单继承性)
Person 
public class Person {//属性String name;private int age;//方法public void eat(){System.out.println("人吃饭");}public void sleep(){System.out.println("人睡觉");}public void show(){System.out.println("age = " + age);}public int getAge() {return age;}public void setAge(int age) {this.age = age;}
}Student 
public class Student extends Person {//属性
//    String name;
//    int age;String school;String Study;//方法
//    public void eat(){
//        System.out.println("人吃饭");
//    }
//    public void sleep(){
//        System.out.println("人睡觉");
//    }public void study(){System.out.println("学生学习");}public void show1() {
//        System.out.println("age : " + age); //封装的属性不能被继承System.out.println("age : " + getAge());}
}ExtendsTest 
public class ExtendsTest {public static void main(String[] args) {Person p1 = new Person();p1.name = "Tom";
//        p1.age = 10; //私有封装的属性不能被访问p1.eat();System.out.println(p1.toString());Student s1 = new Student();s1.name = "Jack";
//        s1.age = 12;//私有封装的属性不能被访问s1.eat();// 超纲:获取s1所属类的父类System.out.println(s1.getClass().getSuperclass()); //class com.atguigu03._extends.Person// 超纲:获取p1所属类的父类System.out.println(p1.getClass().getSuperclass()); //class java.lang.Object}
}

练习题:

案例:
(1)定义一个ManKind类,包括
成员变量int sex和int salary;
方法void manOrWoman():根据sex的值显示“man”(sex==1)或者“woman”(sex==0);
方法void employeed():根据salary的值显示“no job”(salary==0)或者“ job”(salary!=0)。
(2)定义类Kids继承ManKind,并包括
成员变量int yearsOld;
方法printAge()打印yearsOld的值。
(3)定义类KidsTest,在类的main方法中实例化Kids的对象someKid,用该对象访问
其父类的成员变量及方法。
ManKind 
public class ManKind {private int sex;int salary;public ManKind() {}public ManKind(int sex, int salary) {this.sex = sex;this.salary = salary;}public int getSex() {return sex;}public void setSex(int sex) {this.sex = sex;}public int getSalary() {return salary;}public void setSalary(int salary) {this.salary = salary;}public void manOrWoman(){if(sex == 1){System.out.println("Man");}else if(sex == 0){System.out.println("Women");}}public void employeed(){if(salary == 0){System.out.println("no job");}else if(salary != 0) {System.out.println("job");}}}Kids 
public class Kids extends ManKind {private int yearsOld;public Kids() {}public Kids(int yearsOld) {this.yearsOld = yearsOld;}//通过这个构造器可以直接给kid赋值所有属性,而不用分别设置set...public Kids(int sex, int salary, int yearsOld) {this.yearsOld = yearsOld;setSex(sex);setSalary(salary);}public int getYearsOld() {return yearsOld;}public void setYearsOld(int yearsOld) {this.yearsOld = yearsOld;}public void printAge() {System.out.println("I am " + yearsOld + " years old.");}
}KidsTest 
public class KidsTest {public static void main(String[] args) {Kids kid = new Kids();kid.setSex(1);kid.setSalary(100);kid.setYearsOld(12);//来自于父类当中的方法kid.employeed(); //jobkid.manOrWoman(); //Man//Kids类自己声明的方法kid.printAge(); //I am 12 years old.}
}

方法的重写(override/overwrite)

总结和练习: 

一、测武4种权限修饰
在com.atguigu04.override包下创建两个package:test1和test2,测试Java中提供的4种杈限修饰实际开发中,各权限修饰的使用频率是怎样的? public、private是使用频率最高的!二、方法的重写 (overwrite / override)1,为什么需要方法的重写?
子类在继承父类以后,就获取了父类中声明的所有的方法。但是,父类中的方法可能不太适用于子类,换句话说,子类
需要对父类中继承过来的方法进行覆盖、覆写的操作。举例(银行账户):
class Account{//账户double balance;//余额//取钱public void withdraw(double amt){//判断balance余额是否够amt取钱的额度}
}
class CheckAccount extends Account{//信用卡double protectedBy; //透支额度public void withdraw(double amt){//判断balance余额是否够amt取钱的额度//如果不够,还可以考虑从protectedBy额度里取}
}class AccountTest{public static void main(string[] args){CheckAccount acct=new CheckAccount();acct.withdraw(); //执行的是子类重写父类的方法}
}2.何为方法的重写?
子类对父类继承过来的方法进行的覆盖、覆写的操作,就称为方法的重写,3.方法重写应遵循的规则
[复习]方法声明的格式:权限修饰符 返值类型 方法名(形参列表) [throws 异常类型] {//方法体}具体规则:
① 父类被重写的方法与子类重写的方法的方法名和形参列表必须相同。
② 子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符>子类不能重写父类中声明为private权限修饰的方法。
③ 关于返回值类型:> 父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型必须是void> 父类被重写的方法的返回值类型是基本数据类型,则子类重写的方法的返回值类型必须与被重写的方法的返回值类型相同> 父类被重写的方法的返回值类型是引用数据类型(比如类),则子类重写的方法的返回值类型可以与被重写的方法的返回值类型相同 或 是被重写的方法的返回值类型的子类
④ (超纲)子类重写的方法抛出的异常类型可以与父类被重写的方法抛出的异常类型相同,或是父类被重写的方法抛出的异常类型的子类
补充说明:方法体:没有要求。但是子类重写的方法的方法体必然与父类被重写的方法的不同4.面试题:区分方法的重载(overload)与重写(override / overwrite)
重载:"两同一不同"
重写:继承以后,子类覆盖父类中同名同参数的方法[类比]相同类型的面试题:throws /throw
final /finally /finalize
Collection /Collections
String /stringBuffer /stringBuilder
ArrayList /LinkedList
HashMap /LinkedHashMap /Hashtable
...sleep()/ wait()
==/ equals()
同步 /异步
Person 
public class Person {//属性String name;private int age;//方法public void eat(){System.out.println("人吃饭");}public void sleep(){System.out.println("人睡觉");}public void show(){System.out.println("age = " + age);}public int getAge() {return age;}public void setAge(int age) {this.age = age;}//overridepublic int info(){return 1;}public Person info1() {return null;}
}Student 
public class Student extends Person {//属性String school;String Study;public void study(){System.out.println("学生学习");}public void eat(){System.out.println("学生应该多吃有营养的食物");}public void show1() {System.out.println("age : " + getAge());}//重写针对于返回值的测试public int info(){return 1;}//错误
//    public byte info(){
//        return 1;
//    }
//    public long info(){
//        return 1;
//    }public Student info1() {return null;}//错误
//    public Object info1() {
//        return null;
//    }
//    public Person info1() {
//        return null;
//    }public void sleep(){System.out.println("学生应该多睡,养大脑");}
}overrirdeTest
public class overrirdeTest {public static void main(String[] args) {Student s1 = new Student();s1.eat();s1.sleep();}
}

关键字—super

当子类与父类有相同的属性时,执行编译时可以区分开

练习:

案例:1、写一个名为Account的类模拟账户。该类的属性和方法如下图所示
该类包括的属性:账号id,余额balance,年利率annualInterestRate;
包含的方法:访问器方法(getter和setter方法),返回月利率的方法getMonthlyInterest(),取款方法withdraw写一个用户程序测试Account类。在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%的Account对象
使用withdraw方法提款30000元,并打印余额。
再使用withdraw方法提款2500元,使用deposit方法存款3000元,然后打印余额和月利率。提示:在提款方法withdraw中,需要判断用户余额是否能够满足提款数额的要求,如果不能,应给出提示。
运行结果如图所示。2、创建Account类的一个子类checkAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额。
在CheckAccount类中重写withdraw方法,其算法如下:
——————————————————————————————————————————
如果(取款金额<账户余额)
可直接取款
如果(取款金额>账户余额)
计算需要透支的额度提示用户超过可透支额的限额
———————————————————————————————————————————
要求:写一个用户程序测试CheckAccount类。
在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%,可透支限额为5000元的CheckAccount对象。使用withdraw方法提款5000元,并打印账户余额和可透支额。
再使用withdraw方法提款18000元,并打印账户余额和可透支额
再使用withdraw方法提款3000元,并打印账户余额和可透支额。提示:
(1)子类CheckAccount的构造方法需要将从父类继承的3个属性和子类自己的属性全部初始化。
(2)父类Account的属性balance被设置为private,但在子类checkAccount的withdraw方法中需要修改它的值,
类图Account:
运行结果如下图所示。

Account 
public class Account {private int id;private double balance;private double annualInterestRate; // 年利率//    public Account() {}public Account(int id, double balance, double annualInterestRate) {//super()this.id = id;this.balance = balance;this.annualInterestRate = annualInterestRate;}public int getId() {return id;}public void setId(int id) {this.id = id;}public double getBalance() {return balance;}//    public void setBalance(double balance) {
//        this.balance = balance;
//    }public double getAnnualInterestRate() {return annualInterestRate;}public void setAnnualInterestRate(double annualInterestRate) {this.annualInterestRate = annualInterestRate;}public double getMonthlyInterest(){return annualInterestRate / 12;}/*** 取钱操作* @param amount 要取的钱数*/public void withdraw(double amount){if(balance >= amount && amount > 0) {balance -= amount;}else {System.out.println("余额不足!");}}/*** 存钱的操作* @param amount 要存的额度*/public void deposit(double amount){if(amount > 0){balance += amount;}}
}AccountTest 
public class AccountTest {public static void main(String[] args) {Account acct = new Account(1112,20000,0.045);acct.withdraw(30000);System.out.println("您的账户余额为:" + acct.getBalance());acct.withdraw(2500);acct.deposit(3000);System.out.println("您的账户余额为:" + acct.getBalance());System.out.println("月利率为" + acct.getMonthlyInterest());}
}CheckAccount 
public class CheckAccount extends Account{private double overdraft; //可透支限额public CheckAccount(int id, double balance, double annualInterestRate){super(id, balance, annualInterestRate); //默认会调用父类空参的构造器,如果父类没有空参构造器,就可以调用无参的构造器}public CheckAccount(int id, double balance, double annualInterestRate, double overdraft) {super(id, balance, annualInterestRate);this.overdraft = overdraft;}public double getOverdraft() {return overdraft;}public void setOverdraft(double overdraft) {this.overdraft = overdraft;}/*** 针对可透支的账户的取钱的操作* @param amount 要取的钱数*/public void withdraw(double amount){if(getBalance() >= amount){//错误的: getBalance() 是一个值
//            getBalance() = getBalance() - amount;//正确的,但是直接重置账户余额可以容易误操作,直接调用取钱的方法会更加方便
//            setBalance(getBalance() - amount);super.withdraw(amount);}else if(getBalance() + overdraft >= amount){//注意一下先取那个钱的操作,先取透支额度当中的钱,再取余额当中的钱,因为运算中会涉及到余额,如果先取余额了,那么余额就为0了,这样运算,透支的就是要取的钱overdraft -= amount - getBalance();super.withdraw(getBalance());}else{System.out.println("超过可透支限额");}}
}CheckAccoutTest 
public class CheckAccoutTest {public static void main(String[] args) {CheckAccount checkAccount = new CheckAccount(1112,20000,0.045,5000);checkAccount.withdraw(5000);System.out.println("您的账户余额:" + checkAccount.getBalance()); // 15000.0System.out.println("您的可透支余额:" + checkAccount.getOverdraft()); //5000.0checkAccount.withdraw(18000);System.out.println("您的账户余额:" + checkAccount.getBalance()); //0.0System.out.println("您的可透支余额:" + checkAccount.getOverdraft()); //2000.0}
}

面试题1(看执行结果):

public class interview01 {public static void main(String[] args) {new A(new B());}
}
class A {public A(){System.out.println("A");}public A(B b){this();System.out.println("AB");}
}
/*** 打印顺序   new A(new B());* B* A* AB*/
//class B {
//    public B(){
//        System.out.println("B");
//    }
//}/*** 执行顺序  new A(new B());* A* B* A* AB*/
class B extends A {public B(){System.out.println("B");}
}

面试题2(看执行结果):

public class interview02 {public static void main(String[] args) {Father f = new Father();Son s = new Son();System.out.println(f.getInfo()); //atguiguSystem.out.println(s.getInfo()); //atguigus.test(); //atguigu atguiguSystem.out.println("-------------------------");s.setInfo("大硅谷");System.out.println(f.getInfo()); //atguiguSystem.out.println(s.getInfo()); //大硅谷s.test(); //大硅谷  大硅谷}
}
class Father {private String info = "atguigu";public String getInfo() {
//        System.out.println( this.info + "9");return info;}public void setInfo(String info) {
//        System.out.println( this.info + "9");this.info = info;}
}
class Son extends Father {private String info = "尚硅谷";public void test(){System.out.println(this.getInfo()); //this和super调用的都是父类的getInfoSystem.out.println(super.getInfo()); //s这个对象把父类的info更改了}/*** 加了getInfo之后的执行顺序,没重写之前改的是父类的info* atguigu* 尚硅谷* 尚硅谷* atguigu* -------------------------* atguigu* 尚硅谷* 尚硅谷* 大硅谷  s.setInfo("大硅谷"); 只在父类当中有这个方法,此时更改的是父类的info* @return*/public String getInfo(){return info;}
}

总结: 

一、super关键字的使用1.为什么需要super?举例1:子类继承父类以后,对父类的方法进行了重写,那么在子类中,是否还可以对父类中被重写的方法进行调用?
可以!举例2:子类继承父类以后,发现子类和父类中定义了同名的属性,是否可以在子类中区分两个同名的属性?
可以!如何调用? 使用super关键字即可。2.super的理解: 父类的3.super可以调用的结构:属性、方法、构造器具体的:
3.1 super调用属性、方法
子类继承父类以后,我们就可以在子类的方法或构造器中,调用父类中声明的属性或方法。(满足封装性的前提下)
如何调用呢?需要使用"super."的结构,表示调用父类的属性或方法。
一般情况下,我们可以考虑省略"super."的结构。但是,如果出现子类重写了父类的方法或子父类中出现了同名的属性时,
则必须使用"super."的声明,显式的调用父类被重写的方法或父类中声明的同名的属性。3.2 super调用构造器
① 子类继承父类时,不会继承父类的构造器。只能通过"super(形参列表)"的方式调用父类指定的构造器
② 规定:"super(形参列表)",必须声明在构造器的首行。
③ 我们前面讲过,在构造器的首行可以使用"this(形参列表),调用本类中重载的构造器,结合②,结论:在构造器的首行,"this(形参列表)"和"super(形参列表)"只能二选一。
④ 如果在子类构造器的首行既没有显示调用"this(形参列表)",也没有显式调用"super(形参列表)",则子类此构造器默认调用"super()",即调用父类中空参的构造器。
⑤ 由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器。只能是这两种情况之一。
⑥ 由⑤得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了"this(形参列表)",则剩下的那个一定使用"super(形参列表)"。--->  我们在通过子类的构造器创建对象时,一定在调用子类构造器的过程中,直接或间接的调用到父类的构造器。
也正因为调用过父类的构造器,我们才会将父类中声明的属性或方法加载到内存中,供子类对象使用。二、子类对象实例化全过程代码举例:
class Creature{//生物类//声明属性、方法、构造器
}class Animal extends Creature{ //动物类}class Dog extends Animal{ //狗类}class DogTest{public static void main(string[] args){Dog dog = new Dog();dog.xxx();dog.yyy = ....;}
}1.从结果的角度来看:
当我们创建子类对象后,子类对象就获取了其父类对象中所有的属性和方法,在权限允许的情况下,可以直接调用2.从过程的角度来看:
当我们通过子类的构造器创建对象时,子类的构造器一定会直接或间接的调用到其父类的构造器,而其父类的构造器
同样会直接或间接的调用到其父类的父类的构造器,.....,直到调用了0bject类中的构造器为止。正因为我们调用过子类所有的父类的构造器,所以我们就会将父类中声明的属性、方法加载到内存中,供子类的对象使用问题:在创建子类对象的过程中,一定会调用父类中的构造器吗? yes!3.问题:创建子类的对象时,内存中到底有几个对象?就只有一个对象!即为当前new后面构造器对应的类的对象。

子类对象的实例化过程

面向对象特征之三:多态性

查看字节码文件:

编译的时候会认为我们还是调用的person里面的方法,注意前面的virtual是虚拟的意思,调用我们这个虚的方法,编译时方法,也即是父类当中的方法,运行时会动态绑定创建的对象的方法

虚拟方法调用

方法的重载与重写

instanceof 操作符

对象类型转换 (Casting )

这个地方的逻辑,传谁就造谁的对象,可以用于区分是登录还是注册的情况

总结:


1.如何理解多态性?
理解:理解为一个事物的多种形态。生活举例:
> 女朋友:我想养一个宠物。
> 孩子:我想要一个玩具
> 老板:张秘书,安排一个技术科的同事,跟我一起下周出差。2.Java中多态性的体现:子类对象的多态性:父类的引用指向子类的对象。(或子类的对象赋给父类的引用)比如:Person p2 = new Man();3.多态性的应用:
多态性的应用:虚拟方法的调用
在多态的场景下,调用方法时,编译时,认为方法是左边声明的父类的类型的方案(即被重写的方法)执行时,实际执行的是子类重写父类的方法
简称为:编译看左边,运行看右边4.多态性的使用前提:①要有类的继承关系 ②要有方法的重写5.多态的适用性: 仅适用于方法,不适用于属性6.多态的好处与弊端
6.1 弊端:
在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法。但是由于声明为父类的引用,
导致我们没有办法直接调用子类特有的属性和方法。6.2 好处:
极大的减少了代码的冗余,不需要定义多个重载的方法。举例:
class Account{public void withdraw(){} //取钱
}class CheckAccount extends Account{//存在方法的重写public void withdraw(){} //取钱
}class SavingAccount extends Account{//存在方法的重写
}class Customer {Account account;public void setAccount(Account account) {// Account account = new CheckAccount();this.account = account;}public Account getAccount(){return accout;}
}class CustomerTest{main(){Customer cust = new Customer();cust.setAccount(new CheckAccount());cust.getAccount().witidraw();}
}7.instanceof的使用
/*** 1.建议在向下转型之前使用instanceof进行判断,避免出现类型转换异常
* 2.格式: a instanceof A : 判断对象a是否是类A的实例
* 3.如果 a istanceof A 返回true,则:
*       a instanceof superA 返回true,其中,A 是superA的子类
*/

面试题1:

FieldMethodTest 
public class FieldMethodTest {public static void main(String[] args) {Sub s = new Sub();System.out.println(s.count); //20s.display();//20//相当于Base b = new Sub();Base b = s; //多态的特点,运行看右边,编译看左边,针对于方法来说的话,属性没有这样的特点System.out.println(b == s); // trueSystem.out.println(b.count); //10b.display();//20Base b1 = new Sub();System.out.println(b1.count); //10b1.display(); //10}
}
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);}
}

Object 类的使用

==操作符与equals方法

练习题: 

public class UserTest {public static void main(String[] args) {User u1 = new User("Tom", 12);User u2 = new User("Tom", 12);
//        System.out.println(u1.equals(u2));  //false 重写equals前比较的是地址值System.out.println(u1.equals(u2));  //true 重写equals后比较的是内容String str1 = new String("hello");String str2 = new String("hello");System.out.println(str1 == str2); //falseSystem.out.println(str1.equals(str2)); //trueFile file1 = new File("d:\\abc.txt");File file2 = new File("d:\\abc.txt");System.out.println(file1.equals(file2)); //true//数组上使用equals()int[] arr = new int[10];System.out.println(arr.equals(new int[20])); //falseSystem.out.println(arr.equals(new int[10])); //false}
}
class  User {String name;int age;public User(){}public User(String name, int age) {this.name = name;this.age = age;}//重写equals,手动实现//    @Override
//    public boolean equals(Object obj) {return super.equals(obj);
//        if(this == obj){
//            return true;
//        }
//        if(obj instanceof User){
//            User user = (User)obj;if(this.age == user.age && this.name.equals(user.name)){return true;}else {return false;}
//            return this.age == user.age && this.name.equals(user.name);
//        }
//        return false;
//    }//    IDEA自动实现@Overridepublic boolean equals(Object o) {if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return age == user.age && Objects.equals(name, user.name);}
}

 

toString() 方法

ctrl+n调用出需要搜索的内容,从jdk8与jdk17里面

 

总结:

0bject类的概述
1.0bject类的说明
> 明确:java.lang.0bject
> 任何一个Java类(除0bject类)都直接或间接的继承于0bject类
> 0bject类称为java类的根父类
> 0bject类中声明的结构(属性、方法等)就具有通用性> 0bject类中没有声明属性> 0bject类提供了一个空参的构造器> 重点关注:0bject类中声明的方法2.常用方法重点方法:equals() \ toString()了解方法:clone() \ finalize()目前不需要关注:getClass()\hashCode()\ notify()\ notifyAll()\ wait()\ wait(xxx)\ wait(xxx,yyy)面试题:final、finally、finalize 的区别3.equals()的使用
3.1 适用性:
任何引用数据类型都可以使用。3.2 java.lang.0bject类中equals()的定义
public boolean equals(object obj){return (this == obj);
}3.3 子类使用说明:
> 自定义的类在没有重写0biect中equals()方法的情况下,调用的就是0bject类中声明的equals(), 比较两个对象的引用地址是否相同。(或比较两个对象是否指向了堆空间中的同一个对象实体)> 对于像String、File、Date和包装类等,它们都重写了0bject类中的equals()方法,用于比较两个对象的实体内容是否相等。3.4 开发中使用说明:
> 实际开发中,针对于自定义的类,常常会判断两个对象是否equals(),而此时主要是判断两个对象的属性值是否相等
所以:我们要重写0bject类的equals()方法。
> 如何重写:> 手动自己实现>调用IDEA自动实现(推荐)3.5 高频面试题:区分 == 和 equals()
==:运算符
① 使用范围:基本数据类型、引用数据类型
② 基本数据类型:判断数据值是否相等int i1 = 10;
int i2 = 10;
sout(i1 == i2);//truechar c1='A';
int i3 = 65;
sout(c1 == i3);//truefloat f1 = 12.0F;
int i4 = 12;
sout(f1 == i4);//true引用数据类型变量:比较两个引用变量的地址值是否相等。(或比较两个引用是否指向同一个对象实体)equals():方法
> 使用范围:只能使用在引用数据类型上。
> 具体使用:对于类来说,重写equals()和不重写equals()的区别。4.toString()的使用4.1 0bject类中toString()的定义:
public String toString() {return getClass().getName() + "@" + Integer.toHexString(hashCode());
}4.2 开发中的使用场景
> 平时我们在调用System.out.println()打印对象引用变量时,其实就调用了对象的toString()4.3 子类使用说明:
> 自定义的类,在没有重写0bject类的toString()的情况下,默认返回的是当前对象的地址值。
> 像String、File、Date或包装类等0bject的子类,它们都重写了0bject类的tostring(),在调用toString()时,返回当前对象的实体内容。4.4 开发中使用说明:
> 习惯上,开发中对于自定义的类在调用toString()时,也希望显示其对象的实体内容,而非地址值。这时候,就需要重写0bject类中的toString().
public class ToString {public static void main(String[] args) {User u1 = new User("Tom", 23);System.out.println(u1.toString()); //com.atguigu07.object.toString.User@6504e3b2 ---> User{ name = Tom, age = 23 }System.out.println(u1); //com.atguigu07.object.toString.User@6504e3b2String s1 = new String("hello");System.out.println(s1.toString()); //hello   重写了的File file = new File("d:\\abc.txt");System.out.println(file); //d:\abc.txtDate date = new Date();System.out.println(date); //Sun Mar 23 16:25:31 CST 2025}
}
class User{String name;int age;public User(){};public User(String name, int age) {this.name = name;this.age = age;}//手动实现toString()
//    public String toString(){
//        return "User{ name = " + name + ", age = " + age + " }";
//    }@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", age=" + age +'}';}
}

练习题:

 案例: 定义两个类,父类Geometric0bject代表几何形状,子类circle代表圆形。 写一个测试类,创建两个Circle对象,判断其颜色是否相等;利用equals方法判断其半径是否相等; 利用toString()方法输出其半径。

 

Geometric0bject 
public class Geometric0bject {protected String color;protected double weight;public Geometric0bject() {color = "white";weight = 1.0;}public Geometric0bject(String color, double weight) {this.color = color;this.weight = weight;}public String getColor() {return color;}public void setColor(String color) {this.color = color;}public double getWeight() {return weight;}public void setWeight(double weight) {this.weight = weight;}
}Circle 
public class Circle extends Geometric0bject {private double radius;public Circle() {
//        color = "white";
//        weight = 1.0;radius = 1.0;};public Circle(double radius) {
//        color = "white";
//        weight = 1.0;this.radius = radius;};public Circle(String color, double weight, double radius) {super(color, weight);this.radius = radius;}public double getRadius() {return radius;}public void setRadius(double radius) {this.radius = radius;}//求圆的面积public double findArea(){return 3.14 * radius * radius;}//重写equals@Overridepublic boolean equals(Object obj) {if(this == obj){return true;}if(obj instanceof Circle){Circle c = (Circle)obj;return this.radius == c.radius;}return false;}//重写toString()@Overridepublic String toString() {return "Circle[radius = " + radius + "]";}
}CircleTest 
public class CircleTest {public static void main(String[] args) {Circle c1 = new Circle(2.3);Circle c2 = new Circle("red",2.0,3.4);System.out.println("颜色是否相等?" + c1.getColor().equals(c2.getColor()));System.out.println("半径是否相等?" + c1.equals(c2)); //equals当中比较的就是半径System.out.println(c1); //Circle[radius = 2.3]System.out.println(c1.toString()); //Circle[radius = 2.3]}
}

相关文章:

java学习笔记6

按住shift键&#xff0c;选择开始的一位和最后结束的一位来全选 面向对象特征之二&#xff1a;继承性(inheritance) 面向对象特征之二:继承性1.继承性的理解 > 生活上:财产的继承、颜值的继承 > 代码层面:> 自上而下:定义了一个类A&#xff0c;在定义另一个类B时&…...

人工智能在现代科技中的应用和未来发展趋势

人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;是一种模拟人类智能思维和行为的技术&#xff0c;已经在现代科技中得到广泛应用。以下是人工智能在现代科技中的应用和未来发展趋势&#xff1a; 应用&#xff1a; 机器学习&#xff1a;机器学习是人工…...

第二十一章:模板与继承_《C++ Templates》notes

模板与继承 重点和难点编译与测试说明第一部分&#xff1a;多选题 (10题)第二部分&#xff1a;设计题 (5题)答案与详解多选题答案&#xff1a;设计题参考答案 测试说明 重点和难点 21.1 空基类优化&#xff08;EBCO&#xff09; 知识点 空基类优化&#xff08;Empty Base Cla…...

STC89C52单片机学习——第35节: [16-1] AD/DA

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.03.23 51单片机学习——第35节: [16-1] AD/DA 前言开发板说明引用解答和科普一、AD问题…...

算法-最大公约数

1、约数&#xff1a; 1.1 试除法求约数 原理&#xff1a;只需要遍历最小的约数即可&#xff0c;较大的那个可以直接算出来。 import java.util.*; public class Main {static Scanner sc new Scanner(System.in);public static void main(String[] args) {int t sc.nextIn…...

在 SaaS 应用上构建 BI 能力的实战之路

SaaS 产品在持续运营过程中积累了大量数据&#xff0c;这些数据不仅是数字的记录&#xff0c;更是洞察市场趋势、优化产品功能、提升用户体验的宝贵资源。 因此&#xff0c;大部分的 SaaS 产品在发展到一定阶段后&#xff0c;都会开始构建自己的报表模块或分析模块&#xff0c;…...

代码随想录刷题day51|(二叉树篇)654.最大二叉树

一、二叉树基础知识 详见&#xff1a;代码随想录刷题day34|&#xff08;二叉树篇&#xff09;二叉树的递归遍历-CSDN博客 二、递归思路 递归三部曲 构造树一般采用前序遍历&#xff0c;因为先构造中间节点&#xff0c;然后递归构造左子树和右子树&#xff1b; 1.递归函数参数…...

深入理解 C++11 智能指针:独占、共享与弱引用的完美管理

文章目录 std::unique_ptr&#xff08;独占式智能指针&#xff09;std::shared_ptr&#xff08;共享式智能指针&#xff09;std::weak_ptr&#xff08;弱引用智能指针&#xff09;示例展示&#xff1a;智能指针的原理内存泄漏**什么是内存泄漏&#xff0c;内存泄漏的危害****如…...

1.2 编译器结构

编译器具有模块化的高层结构。还可以将模块化进一步细化。编译器可以看成多个阶段构成的流水线结构。 一种没有优化的编译器结构 更复杂的编译器结构...

文件操作助手

文件操作助手 在我们实现一个大型项目时&#xff0c;往往会有一个公共模块&#xff0c;这个公共模块是公用的&#xff0c;里面可能会包含文件操作助手、字符串操作助手、时间戳操作助手… 而我们今天就来实现一个文件操作助手&#xff0c;里面包含的功能有&#xff1a; 判断…...

线段树与扫描线 —— 详解算法思想及其C++实现

目录 一、线段树&#xff08;Segment Tree&#xff09; 基本概念 结构 操作 示例代码 二、扫描线&#xff08;Sweep Line&#xff09; 基本概念 应用场景 示例代码&#xff08;矩形面积并集&#xff09; 三、总结 一、线段树&#xff08;Segment Tree&#xff09; 基本…...

Leetcode 刷题笔记1 图论part04

leetcode 110 字符串接龙 def judge(s1, s2):count 0for i in range(len(s1)):if s1[i] ! s2[i]:count 1return count 1if __name__ __main__:n int(input())begin_str, end_str map(str, input().split())if begin_str end_str:print(0)exit()strlist []for _ in ran…...

快速入手:Nacos融合SpringCloud成为注册配置中心

快速入手&#xff1a;Nacos融合SpringCloud成为注册配置中心 前言安装Nacos项目搭建添加配置启动类添加注解运行项目服务调用RestTemplate 模式FeignClient 模式 前言 Spring Cloud是一系列框架的集合&#xff0c;提供了微服务架构下的各种解决方案&#xff0c;如服务治理、配…...

others-rustdesk远程

title: others-rustdesk远程 categories: Others tags: [others, 远程] date: 2025-03-19 10:19:34 comments: false mathjax: true toc: true others-rustdesk远程, 替代 todesk 的解决方案 前篇 官方 服务器 - https://rustdesk.com/docs/zh-cn/self-host/rustdesk-server-o…...

go:前后端分离

1.前端代码 新建一个前端文件夹&#xff0c;在该文件夹下新建一个.html文件&#xff0c;写入自己的html代码。 前端搞定。 2.后端代码 其核心是挂载路由接受前端传来的数据核心代码如下&#xff1a; func main() { // 服务运行提示 fmt.Println("go web server is runn…...

lodash 学习笔记/使用心得

lodash 学习笔记/使用心得 简单记一下 lodash 的一点学习笔记使用心得&#xff0c;最近也是打算清理一下所有的 dead code&#xff0c;然后发现我们用了好多的 lodash 方法。对比了之前的写法&#xff0c;重新看了一下官方文档&#xff0c;再自己重新动手写了点 util 之后发现…...

网络爬虫【爬虫库request】

我叫不三不四&#xff0c;很高兴见到大家&#xff0c;欢迎一起学习交流和进步 今天来讲一讲爬虫 Requests是Python的一个很实用的HTTP客户端库&#xff0c;完全满足如今网络爬虫的需求。与Urllib对比&#xff0c;Requests不仅具备Urllib的全部功能&#xff1b;在开发使用上&…...

AI日报 - 2025年3月24日

&#x1f31f; 今日概览&#xff08;60秒速览&#xff09; ▎&#x1f916; AGI突破 | Lyra生物序列建模架构效率惊人 在100生物任务中达最优&#xff0c;推理速度提升高达12万倍 ▎&#x1f4bc; 商业动向 | OpenAI用户破4亿&#xff0c;Meta与Reliance探讨AI合作 生态扩展与全…...

Android平台毫秒级低延迟HTTP-FLV直播播放器技术探究与实现

一、前言 在移动互联网蓬勃发展的今天&#xff0c;视频播放功能已成为众多Android应用的核心特性之一。面对多样化的视频格式和传输协议&#xff0c;开发一款高效、稳定的视频播放器是许多开发者追求的目标。FLV&#xff08;Flash Video&#xff09;格式&#xff0c;尽管随着H…...

动态规划——混合背包问题

动态规划——混合背包问题 混合背包问题01背包与完全背包的混合&#xff1a;完全背包与多重背包的混合&#xff1a;三种背包混合混合背包OJ汇总 混合背包问题 将01背包、完全背包、多重背包混合起来的背包问题。也就是说&#xff0c;有的物品只可以取一次&#xff08;01背包&a…...

数据库操作练习

一.向heros表中新增一列信息&#xff0c;添加一些约束&#xff0c;并尝试查询一些信息 //向表中添加一列age信息 alter table heros add column age int;//id列添加主键约束&#xff0c;设置自增 alter table heros modify column id int auto_increment primary key;//name列…...

3.milvus索引-HNSW

索引作用 加速大型数据集上的查询。 向量字段&#xff0c;仅只能创建一个索引。 milvus支持的向量索引类型大部分使用 近似最近邻搜索算法。ANNS该算法的核心不局限于返回最准确的结果&#xff0c;而是仅搜索目标的邻居。ANNS通过在可接受的范围内牺牲准确性提高检索效率。 …...

算法基础——栈

一、栈的概念 栈是⼀种只允许在⼀端进⾏数据插⼊和删除操作的线性表。 进⾏数据插⼊或删除的⼀端称为栈顶&#xff0c;另⼀端称为栈底。不含元素的栈称为空栈。进栈就是往栈中放⼊元素&#xff0c;出栈就是将元素弹出栈顶。 二、栈的模拟实现 1. 创建 本质还是线性表&#…...

开发语言漫谈-groovy

groovy是一门脚本语言&#xff0c;在前期的脚本语言中简单介绍了下。现在再深入介绍下&#xff0c;因为它是本平台上选用的脚本语言。所谓脚本语言就是不用编译&#xff0c;直接执行。这种特色非常适合做嵌入编程&#xff0c;即编即用。我们知道平台后台的业务开发语言是Java&a…...

ArkUI-List组件

列表是一个复杂的容器&#xff0c;当列表项达到一定数量&#xff0c;使得列表内容超出其范围的时候&#xff0c;就会自动变为可以滚动。列表适合用来展现同类数据类型。 List组件支持使用&#xff0c;条件渲染&#xff0c;循环渲染&#xff0c;懒加载等渲染控制方式生成子组件…...

数据仓库的 DWD 分层架构:构建高效数据平台的基石

在数据驱动的时代&#xff0c;数据仓库&#xff08;Data Warehouse&#xff09;作为企业数据分析的核心基础设施&#xff0c;扮演着至关重要的角色。而数据仓库的分层设计&#xff0c;则是确保数据高效流转、提升数据质量、支持复杂分析的关键。本文将深入探讨数据仓库的 DWD 分…...

山东大学数据结构课程设计

题目&#xff1a;全国交通咨询模拟系统 问题描述 处于不同目的的旅客对交通工具有不同的要求。例如&#xff0c;因公出差的旅客希望在旅途中的时间尽可能地短&#xff0c;出门旅游的旅客则期望旅费尽可能省&#xff0c;而老年旅客则要求中转次数最少。编织一个全国城市间的交…...

动态规划-01背包

兜兜转转了半天&#xff0c;发现还是Carl写的好。 看过动态规划-基础的读者&#xff0c;大概都清楚。 动态规划是将大问题&#xff0c;分解成子问题。并将子问题的解储存下来&#xff0c;避免重复计算。 而背包问题&#xff0c;就是动态规划延申出来的一个大类。 而01背包&…...

【2025】基于node.js的中医药科普平台的设计与实现(源码、万字文档、图文修改、调试答疑)

项目完整功能以演示视频为准 基于Node.js的中医药科普平台的设计与实现功能结构图如下 课题背景 随着人们健康意识的提高&#xff0c;中医药作为传统医学的重要组成部分&#xff0c;越来越受到关注。然而&#xff0c;中医药知识专业性强&#xff0c;普通大众获取准确、全面的中…...

基于Flux模型的多模态可控图像生成工作流实践

一、技术框架与模型选型 当前图像生成领域对多模态控制与一致性保持的需求日益增强&#xff0c;本文将基于Black Forest Labs推出的Flux.1模型&#xff0c;结合ControlNet的循环一致性优化技术&#xff0c;构建一套融合Canny边缘检测与深度图&#xff08;Depth&#xff09;控制…...

缓存过期时间之逻辑过期

1. 物理不过期&#xff08;Physical Non-Expiration&#xff09; 定义&#xff1a;在Redis中不设置EXPIRE时间&#xff0c;缓存键永久存在&#xff08;除非主动删除或内存淘汰&#xff09;。目的&#xff1a;彻底规避因缓存自动过期导致的击穿&#xff08;单热点失效&#xff…...

JVM类加载过程详解

文章目录 前言1.加载2.链接验证文件格式验证元数据验证字节码验证符号引用验证 准备解析 3.初始化4.类卸载 前言 类从被加载到虚拟机内存中开始到卸载出内存为止&#xff0c;它的整个生命周期可以简单概括为 7 个阶段&#xff1a;加载&#xff08;Loading&#xff09;、验证&a…...

第三十二篇 深入解析Kimball维度建模:构建企业级数据仓库的完整框架

目录 一、维度建模设计原则深度剖析1.1 业务过程驱动设计1.2 星型模式VS雪花模式 二、维度建模五步法实战&#xff08;附完整案例&#xff09;2.1 业务需求映射2.2 模型详细设计2.3 缓慢变化维处理 三、高级建模技术解析3.1 渐变维度桥接表3.2 快照事实表设计 四、性能优化体系…...

WPF 布局中的共性尺寸组(Shared Size Group)

1. 什么是共性尺寸组&#xff1f; 在 WPF 的 Grid 布局中&#xff0c;SharedSizeGroup 允许多个 Grid 共享同一列或行的尺寸&#xff0c;即使它们属于不同的 Grid 也能保持大小一致。这样可以保证界面元素的对齐性&#xff0c;提高布局的一致性。 SharedSizeGroup 主要用于需…...

19 数码管的动态显示

1、八段数码管 八段数码管 是一个 “ 8 ” 字型数码管&#xff0c;分为八段&#xff0c;a b c d e f g dp&#xff0c;其中dp为小数点。每一段为一个发光二极管&#xff0c;这样的 8 段称为 段选信号 。 2、实验 1、实验目标&#xff1a;让六位数码管 从 0 开始记数&#xff0…...

pytorch 笔记:张量索引的维度扩展规则

1 基本原理 在PyTorch中&#xff0c;张量索引的维度扩展规则遵循以下原则&#xff1a; 索引操作的核心规则&#xff1a;​ 当使用索引数组访问张量时&#xff1a; 索引数组的每个元素对应选取原张量的一个子张量结果形状 索引数组形状 原张量剩余维度形状 这么说可能不清…...

课外活动:怎么理解可变成本?

可变成本深度解析 &#x1f9ee; 一、可变成本的本质 #mermaid-svg-qoqQaFxQBuZZfAD2 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-qoqQaFxQBuZZfAD2 .error-icon{fill:#552222;}#mermaid-svg-qoqQaFxQBuZZfAD2 …...

深入理解 JVM 的垃圾收集器:CMS、G1、ZGC

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…...

IDEA 快捷键ctrl+shift+f 无法全局搜索内容的问题及解决办法

本篇文章主要讲解IDEA、phpStrom、webStrom、pyCharm等jetbrains系列编辑器无法进行全局搜索内容问题的主要原因及解决办法。 日期&#xff1a;2025年3月22日 作者&#xff1a;任聪聪 现象描述&#xff1a; 1.按下ctrlshiftf 输入法转为了繁体。 2.快捷键ctrlshiftr 可以全局检…...

智慧高速,安全护航:视频监控平台助力高速公路高效运营

随着我国高速公路里程的不断增长&#xff0c;交通安全和运营效率面临着前所未有的挑战。传统的监控方式已难以满足现代化高速公路管理的需求&#xff0c;而监控视频平台的出现&#xff0c;则为高速公路的安全运营提供了强有力的技术支撑。高速公路视频监控联网解决方案 高速公路…...

括弧匹配检验(信息学奥赛一本通-1354)

【题目描述】 假设表达式中允许包含两种括号&#xff1a;圆括号和方括号&#xff0c;其嵌套的顺序随意&#xff0c;如&#xff08;&#xff3b; &#xff3d;&#xff08;&#xff09;&#xff09;或&#xff3b;&#xff08;&#xff3b; &#xff3d;&#xff3b; &#xff3…...

MacOS安装 nextcloud 的 Virtual File System

需求 在Mac上安装next cloud实现类似 OneDrive 那样&#xff0c;文件直接保存在服务器&#xff0c;需要再下载到本地。 方法 在 官网下载Download for desktop&#xff0c;注意要下对版本&#xff0c;千万别下 Mac OS默认的那个。 安装了登录在配置过程中千万不要设置任何同…...

【秣厉科技】LabVIEW工具包——OpenCV 教程(11):人脸检测与识别

文章目录 前言级联分类器FaceDetectorYNFaceRecognizerSF1. 特征提取2. 人脸对比3. 人脸身份识别&#xff08;最佳匹配法&#xff09; 总结 前言 需要下载安装OpenCV工具包的朋友&#xff0c;请前往 此处 &#xff1b;系统要求&#xff1a;Windows系统&#xff0c;LabVIEW>…...

C++-C++中的几种cast

文章目录 static_castPOD类型互转任意指针类型与void*互转基类继承类之间的互转具有目标类型转换函数的类/单参数的构造函数 dynamic_castreinterpret_cast static_cast 所谓static&#xff0c;意思是在编译期进行的转换&#xff0c;static_允许如下转换&#xff1a; POD类型…...

list的模拟实现和学习

1. list的介绍及使用 说白了就是带头循环双向循环链表 stl 的两大组件就是容器和算法 &#xff0c;他们两个之间是通过迭代器进行联系的 这三种算法函数 迭代器的种类 性质&#xff08;容器底层结构决定&#xff09; 单项&#xff1a; forward_list /哈希(unord…...

程序代码篇---Pyqt的密码界面

文章目录 前言一、代码二、代码解释2.1用户数据库定义2.2窗口初始化2.3认证逻辑2.5角色处理2.6错误处理优化2.7功能扩展说明2.7.1用户类型区分管理员普通用户其他用户 2.7.2安全增强建议 三、运行效果四、运行命令五、界面改进建议5.1密码显示5.2用户头像显示5.3输入框动画效果…...

设计模式的六大原则

设计模式的六大原则 1. 单一职责原则 (Single Responsibility Principle, SRP) 一个类应该只负责一项职责。 示例代码 // 不好的设计&#xff1a;一个类承担多个职责 typedef struct {void (*read_data)(void);void (*process_data)(void);void (*save_data)(void);void (*…...

【Linux】信号:信号保存和处理

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;linux笔记仓 目录 01.阻塞信号信号集 02.捕捉信号sigaction可重入函数volatileSIGCHLD 01.阻塞信号 实际执行信号的处理动作称为信号递达&#xff1a;每个信号都有一个默认行为&#xff0c;例如终…...

Linux 线程概念

目录 一、什么是线程 1. 线程的本质 2. 线程的独有资源 3. 进程与线程关系示意图 二、线程的优缺点 2.1 线程的优点 2.2 线程的缺点 三、线程的异常与用途 1. 线程异常 2. 线程用途 四、进程 VS 线程 1. 核心差异 2. 进程的多个线程共享的资源 3. 进程和线程的关…...

红帽认证工程师价值

红帽认证工程师具有较高的价值&#xff0c;主要体现在以下几个方面&#xff1a; 行业认可度高 国际通用&#xff1a;红帽公司是全球领先的开源解决方案提供商&#xff0c;其认证在全球范围内被广泛认可。无论是在国内还是国外&#xff0c;拥有红帽认证工程师资格证书都能为个人…...