Day08--面向对象3(多态)

Day08–面向对象3(多态)

一、static关键字

1.特点
  • 可以修饰成员变量,成员方法
  • 随着类的加载而加载,优先于对象加载
  • 只加载一次,就会一直存在,不再开辟新空间
  • 全局唯一,全局共享
  • 可以直接被类名调用
  • 静态只能调用静态,非静态可以随意调用
  • static不能和this或者super共用,因为有static时可能还没有对象
2.测试
package cn.tedu.opp;
//测试  static关键字		
/*
 * 总结
 * 1.静态资源进内存的时间早,出内存的时间晚--谨慎使用
 * 2.静态资源随着类的加载二加载--也叫类的资源
 * 3.多了一种调用方式--除了能用对象方式调用,还能用类名直接调用
 * 4.是全局共享的,而且只加载一次(省时间省内存)
 * */
public class Test06_Static {
	public static void main(String[] args) {
		//2.静态资源进内存的时间要早,当类被加载时,静态资源同时也就加载了
		Demo.game();
		System.out.println(Demo.age);
		
		Demo d=new Demo();
		d.eat();
		System.out.println(d.name);
		//1.静态资源---通过对象d访问  或  直接被类名调用
		d.game();
		System.out.println(d.age);
		
		//3.全局唯一,全局共享
		Demo d2=new Demo();
		d2.age=20;
		System.out.println(d.age);//20
	}
}
class Demo{
	//普通资源
	String name;
	public void eat() {
		//5.非静态资源调用静态资源??--可以
		game();
		System.out.println(age);
		System.out.println(name);
		System.out.println("eat...");
	}
	//静态资源--要被static修饰
	static int age =10;
	public static void game() {
		//4.静态资源调用非静态资源??--不行
		//eat();
		//System.out.println(name);
		System.out.println(age);
		System.out.println("game");
	}
}

二、静态代码块

1.概述
  • 通常用来完成项目的初始化,拥有static的所有特点
2.特点
  • 位置是在成员位置
		static{
            .....
        }
3.测试
package cn.tedu.opp;
//测试  静态代码块
/*
 * 总结
 * 1.执行顺序
 * 		当类加载时:执行静态代码块 只执行一次
 * 		当创建对象时:执行构造代码块并且构造代码块优先于构造方法执行
 * 		当方法被调用时:执行局部代码块
 * */
public class Test07_Block {
	public static void main(String[] args) {
		Person2 p = new Person2();
		p.show();
	}
}
class Person2{
	static{
		System.out.println("静态代码块:用来完成项目的初始化(加载的早并且只加载一次)");
	}
	
	{
		System.out.println("构造代码块:提取构造方法的共性");
	}
	
	public Person2() {
		System.out.println("构造方法:用来创建对象");
	}
	
	public void show() {
		System.out.println("局部代码块:控制变量的作用范围");
	}
}

三、final关键字

1.概述
  • 最终的,final的本意是用来, 控制子类重写的现象.
  • 如果父类的某些方法,不许子类修改. 只需要把父类的方法修饰成最终的
2.特点
  • 可以修饰类,不能被继承
  • 可以修饰方法,不能被重写
  • 可以修饰变量,值不能被修改,是一个常量
3.测试
package cn.tedu.opp;
/*
 * 可以修饰类,不能被继承
 * 可以修饰方法,不能被重写
 * 可以修饰变量,值不能被修改,是一个常量
 * */
public class Test01_Final {
	public static void main(String[] args) {
		new Zi2().drink();
	}
}
final class Fu{//1.可以修饰类,不能被继承--The type Zi2 cannot subclass the final class Fu

}
class Fu2{
	//final String NAME="Jack";//3.可以修饰变量,值不能修改--The final field Fu2.Name cannot be assigned
	public static final String NAME="Jack";//常量的标准写法
	
	final public void eat() {//2.可以修饰方法,不能被重写--Cannot override the final method from Fu2
		System.out.println("eating...");
	}
	public void drink() {
		System.out.println("drink");
	}
}
class Zi2 extends Fu2{
	@Override
	public void drink() {
		System.out.println(super.NAME);
		System.out.println("喝汤");
	}
}

四、多态

1.概述
  • 多态是指一个对象有多种形态
    • 好处:提高了程序的灵活性.体现程序的通用性.做出统一调用标准
      • 通用性:多态中,不关心具体子类的类型,屏蔽了子类间的不同,会把子类当父类来看
2.特点
  • 前提: 发生继承关系 + 发生方法重写现象

    • 口诀1: 父类引用 指向 子类对象
    						Animal a = new Dog();
    
    • 口诀2: 编译看左边,运行看右边
      • 想要保存成功,只能使用 左边 父类的
      • 结果以右边 子类 为准
3.入门案例
package cn.tedu.opp;
//测试  多态
public class Test02_Mulity {
	public static void main(String[] args) {
		//2.创建多态对象 -- 口诀1:父类引用 指向 子类对象
		Animal a = new Dog();
		
		//3.使用多态对象 -- 口诀2:编译看左,运行看右
			//- 多态的目的是统一调用标准,标准就是父类!! -
		a.eat();//- a.eat()是父类提供的方法,但运行结果是子类提供的
				//- (方法声明是用了父类的,方法体是用了子类的)
		
		//a.drink();//4.父类中没有的,是子类特有的方法,如果非得用?--多态对象不支持,只能创建子类对象使用
		
	}
}
//1.前提:发生继承关系 + 发生方法重写现象
class Animal{
	public void eat() {
		System.out.println("eating...");
	}
}
class Dog extends Animal{
	
	@Override
	public void eat() {
		System.out.println("non-eating...");
	}
	
	public void drink() {
		System.out.println("drinking...");
	}
}

五、多态的使用

  • 测试
package cn.tedu.opp;
//测试  多态的使用
/*
 * 总结:
 * 在使用多态对象时:
 * 1.调用普通方法:普通方法被重写,所以用了子类的方法体和父类的方法声明
 * 2.调用成员变量:成员变量用父类的
 * 3.调用静态资源时:静态资源用父类的
 * 		原因:因为静态资源不能重写
 * 4.多态中,方法声明一定用父类的!!(父类没声明不能使用)
 * 	  方法体由于存在Override,所以可能使用的是子类的方法体!
 * */
public class Test03_Mulity {
	public static void main(String[] args) {
		//创建多态对象
		Animal2 a = new Dog2();
		a.eat();//1.成员方法被重写了,所以用了子类的方法体和父类的方法声明
		System.out.println(a.name);//2.成员变量用父类的
		a.drink();//3.静态资源用父类的
		Animal2.drink();//eat()是父类的
		new Dog2().drink();
	}
}
class Animal2{
	String name = "小动物";
	public void eat() {
		System.out.println("eat");
	}
	static public void drink() {
		System.out.println("drink");
	}
}
class Dog2 extends Animal2{
	String name = "大黄";
	@Override
	public void eat() {
		System.out.println("non-eat");
	}
	//静态资源可以被重写吗?? -- 不能
	static public void drink() {
		System.out.println("non-drink");
	}
}

六、异常

1.概述
  • 是指程序中出现的bug
2.继承结构
	--Throwable
	--Exception:软件的bug
	--ArrayIndexOutOfBoundException
	--XxxException
	--Error:不是软件问题,不关注
3.异常的处理
  • 捕获:在程序中加代码,自己的问题自己处理
    • 语法:
					try{
						有问题的代码
					}catch(异常类型1 异常名){
						给出合理的解决方案1
					}catch(异常类型2 异常名){
						给出合理的解决方案2
					}catch(异常类型3 异常名){
						给出合理的解决方案3
					}...
  • 抛出:自己的问题不处理,交给调用者处理
    • 语法:在方法声明上,添加代码 throws 异常类型
4.测试
1)捕获异常
package cn.tedu.opp;

import java.util.InputMismatchException;
import java.util.Scanner;

//测试  异常处理
public class Test04_Exception {
	public static void main(String[] args) {
//		method();//暴露 异常
//		method2();//捕获 异常
		method3();//利用多态捕获异常
	}
	
	//暴露 异常
	public static void method() {
		//需求:接收用户输入的两个整数,并做除法运算
		System.out.print("请输入两个整数:");
		int a = new Scanner(System.in).nextInt();
		int b = new Scanner(System.in).nextInt();
		System.out.println(a/b);	
	}
	
	//捕获 异常
	public static void method2() {
		/*
		 * try{
		 * 	有问题的代码
		 * }catch(异常类型 异常名){
		 * 	给出合理的解决方案
		 * }
		 * */
		System.out.print("请输入两个整数:");
		try {
			int a = new Scanner(System.in).nextInt();
			int b = new Scanner(System.in).nextInt();
			System.out.println(a/b);
		}catch(ArithmeticException e) {
			System.out.println("分母不能为零");
		}catch(InputMismatchException e) {
			System.out.println("请输入两个整数");
		}
	}
	
	//利用多态捕获异常
	public static void method3() {
		System.out.print("请输入两个整数:");
		try {
			int a = new Scanner(System.in).nextInt();
			int b = new Scanner(System.in).nextInt();
			System.out.println(a/b);
		}catch(Exception e) {
			//还有很多异常要处理,但是不知道还有几个也不知道叫啥,根本没法写了??? -- 多态
			//多态来解决,多态根本不关心子类叫啥,有几个,把所有子类都当父类来看   Exception
			//反正所有的异常都是Exception的子类,所以只要捕获Exception那么所有异常就能处理了
			System.out.println("程序出错,请重新输入!");
		}
	}
}
2)抛出异常
package cn.tedu.opp;
import java.util.InputMismatchException;
//测试 抛出异常
import java.util.Scanner;

public class Test05_Throws {
	public static void main(String[] args){//抛出Exception时,main方法也要跟着抛出throws Exception,或者捕获
		//		method();//抛出异常

		try {
			method2();
		} catch (Exception e) {//method2抛出啥,这里就捕获啥
			System.out.println("程序错误");
		}
	}

	public static void method() throws ArithmeticException,InputMismatchException {
		//语法:在方法声明上,添加代码throws异常类型
		System.out.print("请输入两个整数:");
		int a = new Scanner(System.in).nextInt();
		int b = new Scanner(System.in).nextInt();
		System.out.println(a/b);
	}

	//直接抛出Exception体现了多态,会把所有子类的异常都抛出
	public static void method2() throws Exception{
		System.out.print("请输入两个整数:");
		int a = new Scanner(System.in).nextInt();
		int b = new Scanner(System.in).nextInt();
		System.out.println(a/b);
	}
}

拓展

1.程序设计题目

​ 事物: 培优班老师 / 高手班老师
​ 共性: 讲课 / 备课
​ 测试: 创建对象测试功能是否正确

2.OCP原则

OCP原则核心含意是:一个好的设计应该能够容纳新的功能需求的增加,但是增加的 方式不是通过修改又有的模块(类) ,而是通过增加新的模块(类)来完成的, 也就是在设计的时候,所有软件组成实体包括接口,函数等必须是可扩展 但不可修改的。

链接:OCP原则

3.向下转型
		Animal a = new Dog();		
		//TODO 多态对象只支持调用父类的功能,如果非要使用子类扩展的功能
		//方法1:创建子类对象
		//方法2:向下造型 -- 把父类类型的a转型子类类型
		Dog d = (Dog)a;//强转
		d.sleep();//子类特有的方法

:Animal是父类,Dog是子类*

4.静态代码块,构造代码块,局部代码块

!!!执行顺序:静态代码块—构造代码块—构造函数

  • 静态代码块:在类加载时就加载,并且只被加载一次,一般用于项目的初始化

  • 构造代码块:在创建对象时会自动调用,每次创建对象都会被调用

  • 局部代码块:方法里的代码块

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值