Object类
类Object是类层次结构的根类。每个类都使用Object作为超类。
1.1 equals()方法
指示其他某个对象是否与此对象“相等”。
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1==s2);//new表示在堆中开辟新的空间存储数据,双等号比较的是new出来的两块对内存
System.out.println(s1.equals(s2));//String类中重写了equals方法,比较的是两个字符串内容是否相等
==操作符与equals方法的区别:
1 ==比较对象的引用(地址)
2 默认情况equals和==一样
3 String类型重写了Object中的equals,所以String比较使用equals方法。
1.2 hashCode()方法
返回该对象的哈希码值。每一个对象的哈希码值唯一
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = obj2;
//obj2与obj3两个对象的哈希码值一样
System.out.println(obj1.hashCode());
System.out.println(obj2.hashCode());
System.out.println(obj3.hashCode());
1.3 getClass()方法
返回此Object的运行时类。通过某个对象通过反射获取类。
Object obj = new Object();
Class cls = obj.getClass();//通过反射获取到了Object类
1.4 toString()方法
返回该对象的字符串表示。可以在自定义类中重写toString方法,以实现是对象转成指定格式的字符串。
public class Person{
String name;
public Person(String name){
this.name = name;
}
//重写toString方法
public String toString(){
return "name="+name;
}
}
public class DemoPerson{
public static void main(String[]args){
Person p = new Person("张三");
System.out.println(p);//输出结果为:name=张三
}
}
第二节: 多态
2.1 什么是多态
在生活中,一个事物有多种表现形态,对象的多种形态,方法的多样性,比如:某个音乐家有三个儿子,大儿子会唱美声,二儿子会唱流行,三儿子会摇滚。
程序中多态:同一个引用类型,使用不同的实例而执行不同操作 ,一句话理解:父类引用,子类对象。
2.2 案例引入:
需求:
1 编写一个宠物类 Pet 属性:id,name,health,love ;方法有print(),打印信息,要封装成员变量
2 两个子类狗狗和猫类,狗狗有品种(strain),猫类有爱好(hobby),重写父类print()方法
3 宠物饿了,需要主人给宠物喂食,狗狗吃狗粮、猫咪吃小鱼,吃完之后健康值狗狗增加3,猫咪增加5。
/*
宠物类
*/
package com.qf.day08;
public class Pet{
private int id; //id 宠物编号
private String name;// 宠物昵称
private int health;// 健康值
private int love;// 亲密度
public void setId(int id){
this.id=id;
}
public int getId(){
return id;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setHealth(int health){
this.health=health;
}
public int getHealth(){
return health;
}
public void setLove(int love){
this.love=love;
}
public int getLove(){
return love;
}
//方法
public void print(){
System.out.println("宠物id:"+this.id+",宠物昵称:"+this.name+",健康值:"+health+",亲密度:"+love);
}
}
/*
dog类继承Pet类
*/
package com.qf.day08;
public class Dog extends Pet{
private String strain;
public void setStrain(String strain){
this.strain=strain;
}
public String getStrain(){
return strain;
}
public void print(){
int id=getId();
String name=getName();
int health=getHealth();
int love=getLove();
System.out.println("狗狗id:"+id+" 昵称:"+name+" 健康值:"+health+" 亲密度:"+love+" 品种:"+strain);
}
public void eat(){
String name=getName();
System.out.println(name+"大口吃狗粮....");
//增加健康值
int health=getHealth();
setHealth(health+3);
}
}
/*
猫类
*/
package com.qf.day08;
public class Cat extends Pet{
private String hobby;
public void setHobby(String hobby){
this.hobby=hobby;
}
public String getHobby(){
return hobby;
}
public void print(){
int id=getId();
String name=getName();
int health=getHealth();
int love=getLove();
System.out.println("猫咪id:"+id+" 昵称:"+name+" 健康值:"+health+" 亲密度:"+love+" 爱好:"+hobby);
}
public void eat(){
String name=getName();
System.out.println(name+"大口吃小鱼....");
//增加健康值
int health=getHealth();
setHealth(health+5);
}
}
/*
主人
*/
package com.qf.day08;
public class Master{
private String name;
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
//喂食
public void feed(Dog d){
System.out.println(name+"要给狗狗喂食物...");
d.eat();
d.print();
}
public void feed(Cat c){
System.out.println(name+"要给猫咪喂食物...");
c.eat();
c.print();
}
}
package com.qf.day08;
public class TestPet{
public static void main(String[] args){
Dog afu=new Dog();
afu.setId(120);
afu.setName("阿福");
afu.setHealth(85);
afu.setLove(90);
afu.setStrain("拉布拉多");
afu.print();
Cat amao=new Cat();
amao.setId(119);
amao.setName("阿猫");
amao.setHealth(90);
amao.setLove(70);
amao.setHobby("爬树");
amao.print();
Master yuhuan=new Master();
yuhuan.setName("玉环");
yuhuan.feed(afu);
yuhuan.feed(amao);
}
}
思考:如果再领养XXX宠物,就需要给XXX喂食,怎么办?
这样频繁修改代码,代码可扩展性、可维护性差。使用多态优化。
2.3 多态实现步骤:
-
1 编写父类、子类,子类重写父类方法
-
2 运行时,使用父类变量,子类的对象
/* public void feed(Dog d){ System.out.println(name+"要给狗狗喂食物..."); d.eat(); d.print(); } public void feed(Cat c){ System.out.println(name+"要给猫咪喂食物..."); c.eat(); c.print(); }*/ public void feed(Pet p){ String n=p.getName(); System.out.println(name+"要给"+n+"喂食物..."); p.eat();//调用子类重写的方法 p.print();//调用子类重写的方法 }
2.4 多态使用形式:
- 1 使用父类作为方法形参实现多态
- 2 使用父类作为方法返回值实现多态
上机练习1:使用多态实现领养宠物,使用父类作为方法返回值
//主人类中添加领养方法
//领养
public Pet adopt(int type){
if(type==1){
Pet d=new Dog();
d.setHealth(80);
d.setLove(50);
return d;
}else if(type==2){
Pet c=new Cat();
c.setHealth(80);
c.setLove(50);
return c;
}else{
return null;
}
}
/*
领养宠物
*/
package com.qf.day08;
import java.util.Scanner;
public class TestPet2{
public static void main(String[] args){
System.out.println("欢迎来到xxx宠物商店.....");
System.out.println("请选择您要领养的宠物类型 1 狗狗 2 猫咪");
Scanner input=new Scanner(System.in);
int choice=input.nextInt();
Master yuhuan=new Master();
Pet p=yuhuan.adopt(choice);
if(p!=null){
System.out.println("领养成功");
p.print();
}else{
System.out.println("领养失败");
}
}
}
2.5 向上转型,向下转型
int a = 1 ; long b = 3;
b = a ; 自动
a = (int) b;
向上转型:将子类的对象赋值给父类变量,自动转换
Pet pet = new Dog();
String str = "abc";
Object obj = str;
注意:
1 <父类型> <引用变量名> = new <子类型>();
2 此时通过父类引用变量调用的方法是子类覆盖或父类的方法
3 此时通过父类引用变量无法调用子类特有的属性和方法
向下转型:将父类的变量赋值给子类变量,强制转换
练习1:实现主人与宠物玩耍功能
//猫咪捉迷藏 猫类中
public void hideAndSeek(){
String name=getName();
System.out.println(name+"玩捉迷藏...");
int health=getHealth();
setHealth(health-5);
}
//接球 狗狗类
public void catchBall(){
String name=getName();
System.out.print(name+"玩接球游戏....");
int health=getHealth();
setHealth(health-3);
}
public void play(Pet pet){
if(pet instanceof Dog){
Dog d=(Dog)pet;
d.catchBall();
}else if(pet instanceof Cat){
Cat c=(Cat)pet;
c.hideAndSeek();
}
}
Object obj = new String("abc");
String str = (String)obj;
注意:
1 <子类型> <引用变量名> = (<子类型> )<父类型的引用变量>;
2 在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转换异常
2.6 instanceof
对象向下转型时,存在一个问题:
若一个父类A的引用a,指向一个子类B的实例,将a赋值给另一个子类C引用时,会抛出java.lang.ClassCastException异常;
抛出异常后程序将不能继续向下执行,为了避免这个异常的抛出,我们可以通过instanceof关键字判断引用指向的实例是否可以进行强制转换成某个子类对象
已知Animal类有两个子类Dog和Cat:
public class Demo{
public static void main(String[]args){
Animal a = new Dog();
check(a);
}
//设计一个方法,判断一个动物是猫还是狗
public static void check(Animal a){
if(a instanceof Dog){
System.out.println("狗");
}else if(a instanceof Cat){
System.out.println("猫");
}
}
}
第三节:final关键字
在Java中声明类、属性和方法时,可以使用关键字final来修饰。
3.1 final修饰变量(成员变量或局部变量),则成为常量,只能赋值一次。
- 修饰成员变量时,定义时同时给出初始值,或在构造方法中赋值
- 修饰局部变量时,只能赋值一次
3.2 final修饰方法,则该方法不能被子类重写
final returnType methodName(paramList){
…
}
3.3 final修饰类,则类不能被继承
final class finalClassName{
…
}