Java(11)多态

什么是多态?

:指的是一个对象的多种形态,使用多态前提是要有继承和接口的实现

  • 1.方法的重载和重写就是一种多态
  • 2.子类对象的多态性
    Pet p1=new Dog(“泰迪”, “小迪”);
  • 1).分类的引用指向的是子类的实例
  • 2).在执行时,调用的是子类的方法,在编译时,调用的是父类的方法
  • 3).编译时,看左边,运行时,看右边

举例说明:
首先简单的建一个宠物类,有昵称和健康值两个属性。

//宠物类
public class Pet {
	
	protected String name="无";//昵称
	protected int health=100;//健康值
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getHealth() {
		return health;
	}
	public void setHealth(int health) {
		this.health = health;
	}
	public Pet(String name, int health) {
		super();
		this.name = name;
		this.health = health;
	}
	
	public Pet(String name) {
		super();
		this.name = name;
	}
	
	public Pet(int health) {
		super();
		this.health = health;
	}
	public Pet() {
		super();
	}
	
	//输出宠物信息
	public void info(){
		System.out.println("名字叫:"+name+",健康值是:"+health);
	}
	
	//宠物吃食
	public void eat(){
		System.out.println("宠物吃饭");
	}
	
}

然后建一个狗类,狗是宠物,所以会继承宠物类。代码如下:
(有自己的品种属性,重写了吃饭方法,输出方法,加了一个睡觉方法)

public class Dog extends Pet{

	private String strain;//品种

	public String getStrain() {
		return strain;
	}

	public void setStrain(String strain) {
		this.strain = strain;
	}
	
	public Dog (String strain,String name){
		super (name);
		this.strain=strain;
	}


	//重写吃饭方法
	public void eat(){
		super.health=super.health+3;
		System.out.println("狗狗吃饱了,健康值加3");
	}
	
	//重写输出方法
	public void info(){
		super.info();
		System.out.println("我是一只:"+this.strain);
	}
	
	//睡觉
	public void sleep(){
		System.out.println("狗狗在呼呼大睡");
	}
}

现在用Test测试一下:

public class Test {

	public static void main(String[] args) {
		
		//创建宠物类对象
		Pet p = new Pet("旺旺");
		p.info();
		p.eat();
		
		//创建狗类对象
		Dog dog = new Dog("金毛","小金");
		dog.info();
		
		//调用吃饭方法
		m.feed(dog);
		m.feed(pe);
		
		//子类对象的多态性
		Pet p1=new Dog("泰迪","小迪");//向上转型
		p1.info();
		//编译期间,程序会把p1当成父类对象,而父类没有sleep()方法
		//p1.sleep();这里会有错误,因为Pet类里没有睡觉方法。

可以看到这里,可以用Pet new一个Dog,不报错误,这就是

向上转型

,“上”可以理解为“父类”。一个子类对象可以转型为父类对象。这就叫子类对象的多态性。(自我感觉跟重写类似)

思考:如果现在就想用p1调用子类独有的方法,怎么做?

:可以强制类型转换,即

向下转型

,怎么用:(在p1前加括号,Dog)跟C语言强制类型转换一样,这样就可以调用Dog类里的sleep方法了。

        Dog dog1=(Dog)p1;//向下转型
		dog1.sleep();

还有一个问题,在建另一个企鹅(Penguin)类:

public class Penguin extends Pet {

	private String sex;//性别

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public Penguin(String sex,String name) {
		super(name);
		this.sex = sex;
	}

	public Penguin() {
		super();
	}
	
	//重写吃饭方法
	public void eat(){
		super.health=super.health+5;
		System.out.println("企鹅吃饱了,健康值加5");
	}
	//重写输出方法
	public void info(){
		super.info();
		System.out.println("我的性别是:"+this.sex);
		
	}
	//游泳
	public void swimming(){
		System.out.println("企鹅游泳 ");
	}
}

发现,同样是继承的Pet类,里边有独有方法swimming.

  • 在测试时,在 Test类里
       Dog dog1=(Dog)p1;
		dog1.sleep();
	两句下面再加两行:
        Penguin pe1=(Penguin) p1;
      	pe1.swimming();

此时,编译Test是没问题的,但是运行会抛出异常ClassCastException
在这里插入图片描述
这是因为,编译时,看左边,运行时,看右边。

  • 编译左边Penguin pe1是没问题的。但是运行时,p1已经转成了dog,把dog转成penguin是有问题的。
    如何解决?用instanceof方法处理一下就可以,语法如下:
    在这里插入图片描述
    此时Test类运行正常。

final关键字

:代表最终的意思

可以修饰什么?
1.修饰类
2.方法
3.成员变量
4.局部变量

修饰类,这个类有什么特点?
1.这个类不能被继承,但是可以继承别的类
在这里插入图片描述
2.final修饰方法,这个方法就是一个最终方法,不能被重写。

测试一下:
(简单一个类,用final定义method() 方法)

public class MyClass {
	
	public final void method(){
		System.out.println("这是一个最终方法");
	}
}

接着用MyClass1类继承MyClass,在子类MyClass1里重写method() 方法,

public class MyClass1 extends MyClass {
	public void method(){
  }
}

报错:
在这里插入图片描述

3.final修饰成员变量,成员变量的值不可改变
1)成员变量就没有默认值了
2)如果使用final关键字,那么要直接对成员变量进行赋值
例如:
(里面的date)

public class Order {

	private int oid;
	private String name;
	private final String date="2020-1-8";
	public int getOid() {
		return oid;
	}
	public void setOid(int oid) {
		this.oid = oid;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getDate() {
		return date;
	}
	public Order(int oid, String name) {
		super();
		this.oid = oid;
		this.name = name;
	}
	public Order() {
		super();
	}
	@Override
	public String toString() {
		return "Order [oid=" + oid + ", name=" + name + ", date=" + date + "]";
	}
}

输出正常。
在这里插入图片描述
4.final修饰局部变量,值不能改变

        final int num=10;
//		num=12; 
		System.out.println(num);

注释部分为错误代码,不能再赋值。
下面这个是可以的:
(不要看混了)

        final int num1;
		num1=20;
		System.out.println(num1);

总结一下:

1.final修饰的类不能被继承。提高安全性,提高程序的可读性。
2.final修饰的方法不能被子类重写。
3.final修饰的属性为常量。一旦初始化后,不可再被赋值。习惯上,常量用大写字符表示。

static关键字

:静态的,可以修饰属性、方法、代码块。

1.static 修饰属性:

1)由类创建的所有对象,都共享这个属性
2)如果其中的一个对象属性值发生了改变,会导致其他对象属性值跟着改变
3)类变量随着类的加载而加载,独一份
4)静态变量可以直接通过“类名.类变量”的方式调用
5)类变量存在静态域中
6)类变量的加载要早于对象

2.static 修饰方法(类方法)

1)随着类加载而加载
2)可以直接通过“类名.方法名”的方式调用
3)内部可以调用静态方法或者是静态属性,不能调用非静态方法和属性,非静态方法可以调用静态变量和静态方法

例子:

  • 创建一个SportsMan对象(名字,年龄,国际三个属性,其中nation用了static关键字,有一个static修饰的show1() 方法(静态方法)。)
public class SportsMan {
//实例对象 ,随着对象的创建而加载
	private String name;
	private int age;
	 static String nation;
	 
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	public SportsMan(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	public SportsMan() {
		super();
	}

	public String getNation() {
		return nation;
	}
	public String setNation(String nation) {
		return nation;
	}
	
	@Override
	public String toString() {
		return "SportsMan [name=" + name + ", age=" + age +", nation=" + nation+ "]";
	}
	
	public void show(){
		System.out.println("这是一个普通方法");
	}
	
	public static void show1(){
//		System.out.println("age:"this.age);
		System.out.println("这是一个静态方法");
	}	
}

Test类测试一下:

public class TestSportsMan {

	public static void main(String[] args) {
		
		SportsMan.nation="11";
		SportsMan s1=new SportsMan("张三",20);
		s1.setNation("中国");
		s1.show();
		System.out.println(s1);
		
		SportsMan.show1();
		SportsMan s2=new SportsMan("李四",67);
		System.out.println(s2);
	}
}

运行结果如下:
在这里插入图片描述
直接通过“类名.方法名”的方式调用。 中间的setNation 没有排上用场,国籍并没有更改。

*注意:静态方法不能使用this和super关键字
在这里插入图片描述

3.static可以修饰代码块

(暂时没有用到,所以只了解即可。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LIUBLOGS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值