java-多态

本文详细介绍了Java中的多态概念,包括多态的前提条件、特点及其优缺点,并通过具体实例展示了如何实现多态以及多态在实际编程中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

多态


封装 继承 多态


1.多态的前提


多态:同一对象,在不同时刻体现出来的不同状态
举例:水(液态,气态,固态)
狗是狗,狗是动物

多态的前提:

  1. 继承关系
  2. 要有方法重写,其实没有也可以,但是如果没有就没有意义
  3. 要有父类引用指向对象
    狗 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();
		}
}

优点:

  1. 提高代码的维修(继承)
  2. 提高代码的扩展性(多态)

缺点:
不能使用子类特有的成员方法

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默认继承过来的是比较内存地址,但是可以重写让它比较属性的值

### 面向对象编程中的多态概念解释 多态是指方法或对象能够表现出多种形式的能力,这是面向对象编程的第三大特性[^1]。它允许程序在不同情况下执行不同的行为,增强了灵活性和扩展性。 #### 多态的具体表现形式 多态可以分为两种主要类型: - **编译时多态(静态多态)** - 主要通过函数重载实现,在编译阶段就决定了具体调用的方法版本[^2]。 - **运行时多态(动态多态)** - 通常由子类覆盖父类的方法来达成,具体的实现取决于实例的实际类型,只有到运行时刻才能确定。 #### 示例说明 下面是一个展示Java多态特性的简单例子,其中包含了方法重写以及向上转型的概念: ```java // 定义一个基类 Animal class Animal { public void makeSound() { System.out.println("Some generic animal sound"); } } // 创建 Dog 类作为 Animal 的子类并重写了 makeSound 方法 class Dog extends Animal { @Override public void makeSound() { System.out.println("Bark!"); } } public class Main { public static void main(String[] args) { // 向上转型:将子类的对象赋给超类类型的变量 Animal myDog = new Dog(); // 调用的是 Dog 中被重写的 makeSound 方法 myDog.makeSound(); // 输出 "Bark!" } } ``` 在这个例子中,`myDog` 是 `Animal` 类型的一个引用,但它指向了一个 `Dog` 对象。当调用 `makeSound()` 方法时,实际上执行的是 `Dog` 类里定义的行为而不是 `Animal` 类里的默认行为,这体现了运行时多态的特点。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值