多态
封装 继承 多态
1.多态的前提
多态:同一对象,在不同时刻体现出来的不同状态
举例:水(液态,气态,固态)
狗是狗,狗是动物
多态的前提:
- 继承关系
- 要有方法重写,其实没有也可以,但是如果没有就没有意义
- 要有父类引用指向对象
狗 d=new 狗();
动物 d=new 狗();
class Animal {
// 成员变量
public int num = 10;
public void show() {
System.out.println("show Animal");
}
public static void function() {
System.out.println("function Animal");
}
}
class Dog extends Animal {
public int num = 100;
public int num2 = 1000;
@Override
public void show() {
System.out.println("show Dog");
}
public void method() {
System.out.println("method dog");
}
//静态方法 静态方法根本就不叫重写
public static void function() {
System.out.println("funtion dog");
}
}
public class AnimalTest {
public static void main(String[] args) {
//多态的前提
//父类引用指向了子类对象
//Animal animal = new Dog();
//Dog dog = new Dog();
//System.out.println(dog.num);//100 覆盖父类的
//System.out.println(dog.num2);//1000 子类特有的
//dog.show();//show Dog
//dog.function();//funtion dog
Animal animal = new Dog();
System.out.println(animal.num);//10
//子类特有的成员变量被屏蔽掉了
//System.out.println(animal.num2);
animal.show();//show Dog
animal.function();//function Animal
//成员变量: A:编译看左边,运行看左边
//成员方法: B:编译看左边,运行看右边 确保重写有意义
//静态方法: C:编译看左边,运行看左边 算不上重写
//多态->编译看父类->重写的时候成员方法看子类,其它全部看父类
}
}
2.多态特点
//成员变量: A:编译看左边,运行看左边
//成员方法: B:编译看左边,运行看右边 确保重写有意义
//静态方法: C:编译看左边,运行看左边 算不上重写
//多态->编译看父类->重写的时候成员方法看子类,其它全部看父类
3.多态的优缺点
class Animal {
public void eat() {
}
public void sleep() {
}
public void show() {
System.out.println("show Animal");
}
}
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
public void sleep() {
System.out.println("猫睡觉");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("狗吃骨头");
}
public void sleep() {
System.out.println("狗睡觉");
}
public void jump() {
System.out.println("跳");
}
}
class Pig extends Animal {
public void eat() {
System.out.println("猪吃草");
}
public void sleep() {
System.out.println("猪睡觉");
}
}
public class AnimalTest {
public static void main(String[] args) {
Cat c = new Cat();
// c.eat();
// c.sleep();
useCat(c);// 猫对象的地址值
Cat c2 = new Cat();
// c2.eat();
// c2.sleep();
useCat(c2);
Cat c3 = new Cat();
// c3.eat();
// c3.sleep();
useCat(c3);
// 创建对象代码接收
// 调用 代码相似 仅仅是对象名不一样
// 养狗
Dog dog = new Dog();
useAnimal(dog);//0x001
//多态
//Animal animal=0x001
//Animal animal=new Dog();
Pig pig=new Pig();
useAnimal(pig);
// 每次班长养了一种新的宠物,都要编写一个新的方法,麻烦
//Animal animal=0x001
public static void useAnimal(Animal animal{
animal.eat();
animal.sleep();
//animal.jump(); 多态的 父类会屏蔽掉子类特有的方法
}
// 调用狗的行为
public static void useDog(Dog dog) {// cat=0x001
dog.eat();
dog.sleep();
}
// 调用猫的行为
public static void useCat(Cat cat) {// cat=0x001
cat.eat();
cat.sleep();
}
}
优点:
- 提高代码的维修(继承)
- 提高代码的扩展性(多态)
缺点:
不能使用子类特有的成员方法
4.多态的理解
class lin爹{
int age=55;
public void teach(){
//教数学
}
}
class lin extends lin爹{
int age=25;
public void teach(){
//教生物
}
public void play(){
//打豆豆
}
}
lin老师装爹的故事
星期一: lin爹出去happy, lin装爹,穿上父亲的衣服,带隐形眼镜,贴上胡子,化妆
//向上转型
lin爹 die=new lin();
//开车去学校
System.out.println(die.age);//55
//讲生物
die.teach();
//打豆豆 不行 因为他爹没有这个功能
//下班了 回家
//脱下衣服 卸妆 向下转型
//向下转型
lin lin=(lin)die;
System.out.println(lin.age);//25
lin.teach();//讲生物
lin.play();//打豆豆
5.多态的内存图
6.Object类
6.1object类概述
//java所有的类会直接或者间接的继承Object类
//Object类是所有类的超类
public class Student extends Object {
public void show() {
System.out.println("show show");
}
}
6.2hasCode方法
内存地址用一个hash算法转成10进制给我们
Student student=new Student();
student.show();
//1.hashCode 内存地址用一个hash算法转成成10进制给我们
System.out.println(student.hashCode());
Student student2=new Student();
System.out.println(student2.hashCode());
6.3getClass
//2.getClass() 返回这个对象类的相关信息
//clazz对象封装了Student这个类的相关信息
Class clazz = student.getClass();
//getName() 返回类的名字
//com.gxa.demo03.Student 全限定名
System.out.println(clazz.getName());
6.4toString方法
//3.toString
//com.gxa.demo03.Student@15db9742
//clazz.getName()+@+hashCode转成16进制
System.out.println(student.toString());
6.5equals方法
比较两个对象是否相等,比较是内存地址
//4.equals
//比较两个对象的内存地址是否相等 如果相等返回true
boolean result = student.equals(student2);
System.out.println(result);
6.6finalize
final finally finalize的区别
垃圾回收器回收这个对象的时候会自动调用这个方法
//java所有的类会直接或者间接的继承Object类
//Object类是所有类的超类
public class Student {
public void show() {
System.out.println("show show");
}
public void finalize() throws Throwable {
System.out.println("小林被回收了");
}
}
student=null;
//呼叫垃圾回收器
//运行垃圾回收器。
System.gc();
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
6.7重写toString
public class Teacher {
private int age;
private String name;
public Teacher() {
super();
}
public Teacher(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher [age=" + age + ", name=" + name + "]";
}
}
public static void main(String[] args) {
Teacher teacher=new Teacher(18,"小小林");
//如果在System直接打印引用类型的变量
//编译后自动调用toString()
System.out.println(teacher);
System.out.println(teacher.toString());
//从Object继承的 打印的内存地址 没有多大意义
//Object帮我们写的这个方法不够强大,重写,输出所有成员变量的值
//重写toString只是为了方便查看属性的结果
Object teacher2=new Teacher(18,"小小林");
//Teacher [age=18, name=小小林]
System.out.println(teacher2);
}
6.8重写equals方法
public class Teacher {
private int age;
private String name;
public Teacher() {
super();
}
public Teacher(int age, String name) {
super();
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Teacher [age=" + age + ", name=" + name + "]";
}
//比较两个对象的所有属性的值是否相等
//如果相等返回true 不相等返回false
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Teacher other = (Teacher) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
Teacher teacher3=teacher2;
//开发业务场景 我们认为只要所有的属性值相同就是同一个对象
System.out.println(teacher2.equals(teacher));//重写比较两个对象属性的值
= = 和equals区别?
int a=5;
int b=5;
a==b
== 如果是基本数据类型比较的是值,如果是引用数据类型比较的是内存地址
equals 从Object默认继承过来的是比较内存地址,但是可以重写让它比较属性的值