示例代码;
/** * 学生类 */ public class Student extends Object{ String stuNo; String stuName; int age; public void show() { System.out.println("学号:"+stuNo+" 姓名:"+stuName+" 年龄:"+age); } @Override public boolean equals(Object obj) { if(obj==null) { return false; } //强制类型转换 //注意:可能的NullPointerException Student stu=(Student)obj; //比较学号和姓名 if(this.stuNo.equals(stu.stuNo)&&this.name.equals(stu.name)){ return true; } return false; } } public class Test { public static void main(String[] args) { Student zhangsan=new Student(); zhangsan.stuNo="bj1805"; zhangsan.stuName="xxx"; zhangsan.age=20; Student lisi=new Student(); lisi.stuNo="bj1805"; lisi.stuName="xxx"; lisi.age=20; boolean b=zhangsan.equals(lisi); boolean b2=zhangsan==lisi; System.out.println(b); System.out.println(b2); } }示例:
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());示例:
Object obj = new Object(); Class cls = obj.getClass();//通过反射获取到了Object类示例
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=张三 } }需求:
编写一个宠物类 Pet, 属性: id,name,health,love;方法有print(),打印信息,要封装成员变量.
两个子类狗狗和猫类,狗狗有品种(strain),猫类有爱好(hobby),重写父类print()方法;
宠物饿了,需要主人给宠物喂食,狗狗吃狗粮、猫咪吃小鱼,吃完之后健康值狗狗增加3斤,猫咪增加5斤.
示例:
/* 宠物类 */ package com.syc.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.syc.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.syc.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.syc.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.syc.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喂食,怎么办? 这样频繁修改代码,代码可扩展性、可维护性差,考虑使用多态来优化代码.
编写父类、子类,子类重写父类方法;
运行时使用父类变量,子类的对象(编译时看父类,运行时看子类).
示例:
/* 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();//调用子类重写的方法 }使用父类作为方法形参实现多态;
使用父类作为方法返回值实现多态.
上机练习:
使用多态实现领养宠物,使用父类作为方法返回值.
//主人类中添加领养方法 //领养 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.syc.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("领养失败"); } } }向上转型:
将子类的对象赋值给父类变量,自动转换.
Pet pet1 = new Dog(); Pet pet2 = new Cat(); String str = "abc"; Object obj = str;注意:
<父类型> <引用变量名> = new <子类型>();
此时通过父类引用变量调用的方法是子类重写或父类的方法, 编译时看父类,运行时看子类;
此时通过父类引用变量无法调用子类特有的属性和方法.
向下转型:
将父类的变量赋值给子类变量,强制转换.
Object obj = new String("abc"); String str = (String)obj; Pet pet=new Dog(); // Pet pet=new Cat(); Dog d=(Dog)pet; //向下转型注意:
<子类型> <引用变量名> = (<子类型> )<父类型的引用变量>;
在向下转型的过程中,如果没有转换为真实子类类型,会出现类型转换异常ClassCastException.
上机练习: 实现主人与宠物玩耍功能
//猫咪捉迷藏: 猫类中 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(); } }对象向下转型时,存在一个问题: 若一个父类A的引用a,指向一个子类B的实例,将a赋值给另一个子类C引用时,会抛出java.lang.ClassCastException异常.
抛出异常后,程序将不能继续向下执行.为了避免这个异常的抛出,我们可以通过instanceof关键字,来判断引用指向的实例是否可以进行强制转换成某个子类对象.
示例:
已知Pet类有两个子类Dog和Cat:
public class Demo{ public static void main(String[]args){ Pet a = new Dog(); check(a); } //设计一个方法,判断一个动物是猫还是狗 public static void check(Pet a){ if(a instanceof Dog){ System.out.println("狗"); }else if(a instanceof Cat){ System.out.println("猫"); } } }final修饰成员变量或局部变量,则成为(符号)常量,只能赋值一次,用大写字母表示.
修饰成员变量时,定义时同时给出初始值,或在构造方法中赋值;
修饰局部变量时,只能赋值一次.
则该方法不能被子类重写,但能被继承.
final returnType methodName(paramList){ ... }一一哥Sun 认证博客专家 Elasticsearch Java 架构 十年软件开发授课经验,专注大学生毕业设计及面试求职私塾式指导!对Android/JavaWeb/微服务/H5等技术领域有深入研究!曾任国内最大的智能物联网平台架构师,参与国内最大的智能物流系统平台天眼/冷链/订单/车次系统研发;曾主导国内首款国学教育App及后台架构;负责大庆油田采油管理系统,铝业云计算系统,湖南广电地面波机顶盒等项目的研发。目前担任某著名培训机构教学主管,培养了大批入职阿里,IBM,百度,国家电网等名企的高薪学生.本人坚持只有一心做教育,才能做一流教育的理念,被学生爱称为"一一哥"!QQ:2312119590,今日头条号:一一哥Sun;知乎ID:一一哥
