JAVA 多态 异常 泛型

多态

多态性是指同一个操作作用于某一类对象,可以有不同的解释,产生不同的执行结果

多态的必要条件和作用

多态的三个必要条件

  1. 需要存在继承和实现关系
  2. 同样的方法调用而执行不同操作 运行不通代码(重写)
  3. 在运行父类或接口的引用变量可以引用某子类的对象

多态的作用
1 多态通过分离做什么和怎么做,从一个角度将接口和实现进行分离
2 多态消除了类型之间的耦合关系
3 多态的存在提高了程序的扩展性和后期的可维护性

有子类转型成父类 叫向上转型。向上转型是从一个较为专业类型向通用类型转换,所以总是安全的。向上转型会造成方法丢失
向下转型则不安全,要先进行判断 判断是否能进行转型(需要instanceof协助)


abstract class Animal{
	abstract void eat();
	
}

class Dog extends Animal{

	public void eat() {
		// TODO Auto-generated method stub
		System.out.println("狗吃骨头");
	}
	public void sleep() {
		System.out.println("狗狗睡觉");
	}
}

class Cat extends Animal{

	public void eat() {
		// TODO Auto-generated method stub
		System.out.println("猫吃鱼");

	}
}

public class Test {
	public static void main(String[] args) {
		Animal an1 = new Dog();
		Animal an2 = new Cat();
	
		an1.eat();
		//an1.sleep(); //向上转型造成方法丢失
		an2.eat();
		if(an2 instanceof Cat){ //向下转型要先进行判断 判断是否能进行转型
			System.out.println("lm");
			Cat cat = (Cat)an2;
			cat.eat();
		}
	}
}

多态的好处:用打印机案例来呈现

import java.util.logging.Handler;




class Dayinji
{
	public String binpai;
	
	public void print(String contex){
		
	}
}

class caise extends Dayinji
{
	public void print(String contex) {
		// TODO Auto-generated method stub
		System.out.println("彩色打印"+contex);
	}
}

class Heibai extends Dayinji
{
	public void print(String contex) {
		// TODO Auto-generated method stub
		System.out.println("黑白打印"+contex);
	}
}

class Zhenshi extends Dayinji
{
	public void print(String contex) {
		// TODO Auto-generated method stub
		System.out.println("针式打印"+contex);
	}
}

class School
{
	public Dayinji dayinji;
	public void anZhuang(Dayinji dayinji){
		this.dayinji = dayinji;
	}
	
	public void print(String contex){
		dayinji.print(contex);
	}
}

public class Test {
	public static void main(String[] args) {
		School s = new School();
		
		caise c = new caise();
		s.anZhuang(c);
		s.print("linruimiao");
		
		Heibai h = new Heibai();
		s.anZhuang(h);
		s.print("lrm");
		
		Zhenshi z = new Zhenshi();
		s.anZhuang(z);
		s.print("linmu");
	}
}

异常

所谓异常是指在程序运行的过程中发生的一些不正常事件。(如:除0溢出,数组下标越界,所要读取的文件不存在)。
JAVA程序的执行过程中取出现异常事件,可以生成一个异常类对象,该异常对象封装了异常事件的信息,并将其被提交给JAVA运行时系统,这个过程称为抛出异常,不处理的话会导致程序直接中断。
设计良好的程序应该在程序异常发生时提供处理这些异常的方法,是的程序不会因为异常的发生而阻断或发生不可预见的结果。
异常的分类
受查异常 Exception及其子类 必须处理
非受查异常 Error和RuntimeException及其子类 可以不处理
JAVA异常处理机制
Try-catch-finally
try:监控区域,执行可能产生异常的代码
catch:捕获 处理异常
finally 善后处理 无论是否发生异常,代码总能执行 一般同来释放资源

异常处理

import java.util.Scanner;


class Person
{
	String name;
	int a;
	int b;
	double c;
}

public class Test {

	public static void main(String[] args) {
		Person p1 = null;
		
		Person p2 = new Person();
		try{
			p1.name = "dfasf";	
		}catch(java.lang.NullPointerException e){
			System.out.println("空指针");
		};
		p2.a = 10;
		p2.b = 0;
		p2.c = 0;
		Scanner sc = new Scanner(System.in);
		System.out.println("请输入一个数");	
		p2.b = sc.nextInt();
		try{
			p2.c = p2.a/p2.b;
		}catch(java.lang.ArithmeticException e){//Exception e 捕获所有异常
			System.out.println("输入错误 重新输入一个数");
			p2.b = sc.nextInt();
			p2.c = (double)p2.a/p2.b;
		};
		System.out.println("c="+p2.c);
		
		System.out.println("end");
	}
}

JAVA: 除数为double 0,不会报错,为无穷大

异常抛出

throw用于手动抛出异常。作为程序员可以在任意位置手动抛出异常。后面跟上要抛出的异常类对象
throws用于在方法上标识要暴露的异常。抛出的异常交由调用者处理。后面跟上可能要抛出的异常类名


class Bar{
	
	int age;
	
	public Bar(int age){
		this.age = age;
		
	}
	void check()throws nianjitaixiaoException{ //声明异常
		if(age < 18){
			throw new nianjitaixiaoException("年纪太小");//手动抛出异常
		}
	}
}

class nianjitaixiaoException extends Exception //自定义异常
//受查异常 不处理编译通不过
{
	private String message;
	public nianjitaixiaoException(String message){
		this.message = message;
	}
}

public class Test {
	
	public static void main(String[] args) {
		Bar b = new Bar(2);
		try{
			b.check();
		}catch(nianjitaixiaoException e){
			System.out.println("年纪太小");
		}
		
		System.out.println("end");
		
	}
}

泛型

泛型可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的(防止误操作)
泛型的原理就是“类型的参数化”就像方法的形式参数是运行时传递的值得占位符一样
泛型可以提高代码的扩展性和重用性

泛型特点

1 泛型类可以设置多个类型参数
2 泛型的类型参数也可以是泛型

import javax.swing.text.GapContent;


class Stduent<T>
{
	T a;
	public Stduent(T a){
		this.a = a;
	}
	public T getdata(){
		return a;
	}
}

class Teacher<T1,T2> //泛型类可以设置多个类型参数
{
	T1 a;
	T2 b;
	
	public Teacher(T1 a, T2 b){
		this.a = a;
		this.b = b;
	}
	public T1 getdata1(){
		return a;
	}
	public T2 getdata2() {
		return b;
	}
}

public class Test {
	public static void main(String[] args) {
 		Stduent<Integer> s = new Stduent<Integer>(5);
 		System.out.println("s="+s.getdata());
 		
 		Stduent<String> a = new Stduent<String>("linruimiao");
 		System.out.println("a="+a.getdata());
 		
 		Teacher<Integer, String> t1 = new Teacher<Integer, String>(100, "lrm");
 		System.out.println("data="+ t1.getdata1());
 		System.out.println("data="+ t1.getdata2()); 
 		System.out.println("data=" + (t1.getdata2()+t1.getdata1()));
 		
 		Teacher<Integer, Integer> t2 = new Teacher<Integer, Integer>(10, 20);
 		System.out.println("data=" +(t2.getdata1()+t2.getdata2()));//都是整形数可以相加
 		Stduent<Stduent<Integer>> b = new Stduent<Stduent<Integer>>(new Stduent<Integer>(100)); //泛型的类型参数也可以是泛型
		System.out.println("data="+ b.getdata().getdata());
	}
}

3 泛型类可以继承泛型类
4 泛型类可以实现接口


abstract class Stduent<T> // 抽象泛型类
{
	T a;
	public Stduent(T a){
		this.a = a;
	}
	public T getdata(){
		return a;
	}
	abstract void printnfo(); 
}

interface Student2<T3> //泛型接口
{
	abstract void printnfot3(T3 t);
}

class Teacher <T,T2,T3> extends Stduent<T> implements Student2<T3> // 继承泛型类  接口
{
	T2 b;
	
	public Teacher(T a, T2 b){
		super(a);
		this.b = b;
	}
	
	public T2 getdata2() {
		return b;
	}

	@Override
	void printnfo() {
		// TODO Auto-generated method stub
		System.out.println("data="+a);
		System.out.println("data="+b);
	}

	public void printnfot3(T3 t) {
		// TODO Auto-generated method stub
		System.out.println("data="+t);
	}
}

public class Test {
	public static void main(String[] args) {
		Teacher<String, Integer,Integer> t = new Teacher<String, Integer,Integer>("linruimiao",100);
		t.printnfo();
		t.printnfot3(450);
		
	}
}

若要限制泛型可用类型 在定义类型时 使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口
当没有指定泛型继承的类型或接口是,默认使用extends Object,所以默认情况下任何类型都可以传入
泛型继承接口都用 extends


class Animal
{
	
}

class Dog extends Animal
{
	int data;
	public Dog(int data){
		this.data = data;
	}
	public int getdata3(){
		return data;
	}
}
interface Move
{
	abstract void printInfo();
}

abstract class Stduent1<T extends Move> // 泛型继承接口都用 extends
{
	
}

abstract class Stduent<T> 
{
	T a;
	public Stduent(T a){
		this.a = a;
	}
	public T getdata(){
		return a;
	}
	abstract void printnfo();
}

interface Student2<T3>
{
	abstract void printnfot3(T3 t);
}



class Teacher <T ,T2 extends Dog,T3> extends Stduent<T> implements Student2<T3>
{
	T2 b;
	
	public Teacher(T a, T2 b){
		super(a);
		this.b = b;
	}
	
	public T2 getdata2() {
		return b;
	}

	@Override
	void printnfo() {
		// TODO Auto-generated method stub
		System.out.println("data="+a);
		System.out.println("data="+b.getdata3());
	}

	public void printnfot3(T3 t) {
		// TODO Auto-generated method stub
		System.out.println("data="+t);
	}
}

public class Test {
	public static void main(String[] args) {
		Teacher<String, Dog, String> t = new Teacher<String, Dog,String>("linruimiao",new Dog(10));
		t.printnfo();
		t.printnfot3("lrm");
		
	}
}

泛型通配符

1 “?”代表任意类型
2 extends限定通配符上限
3 super限定通配符下限

import javax.naming.ldap.ExtendedRequest;


class Animal
{
	
}

class Dog extends Animal
{

}
class Stduent<T> 
{
	T a;
	public Stduent(T a){
		this.a = a;
	}
	
	public T getdata(){
		return a;
	}
	
}
public class Test {
	public static void main(String[] args) {
		Stduent<Integer> s1 = new Stduent<Integer>(10);
		Stduent<String> s2 = new Stduent<String>("linruimiao");
		Stduent<?> s3; // ? 代表任意类型 
		Stduent<? extends Animal> s4; // 必须是Amimal的子类 上限
		Stduent<? super Dog> s5; // 必须是Dog的父类  下限
		Stduent<Dog> s6 = new Stduent<Dog>(new Dog());
		s3 = s1;
		s3 = s2;
		s4 = s6;
		s5 = s6;		
	}
}

泛型方法

相比泛型类更加灵活 但仅对本方法有效 类中的其他方法不能使用当前方法生命的泛型
是否拥有泛型方法,与其所在的类是否泛型没有关系 要定义泛型方法 只需要将泛型参数列表置于返回值前

什么时候使用泛型方法,而不是泛型类
1 添加类型约束只作用于一个方法的多个参数之间,而不是涉及类中的其他方法时
2 施加类型约束的方法为静态方法,只能将其定义为泛型方法,因为静态方法不能使用其所在类的类型约束


abstract class Animal 
{
	abstract void eat();
}

class Dog extends Animal
{

	@Override
	void eat() {
		// TODO Auto-generated method stub
		System.out.println("狗啃骨头");
	}
}

class Cat extends Animal
{

	@Override
	void eat() {
		// TODO Auto-generated method stub
		System.out.println("猫吃鱼");
	}
}

class Person extends Animal
{

	@Override
	void eat() {
		// TODO Auto-generated method stub
		System.out.println("人吃饭");
	}
	
}

class A<T>
{
	public void printInfo3(T t){
		System.out.println(t);
	}
}

class D
{
	public <T> void printInfo(T t){ //泛型方法
		System.out.println(t);
	}
	public static <T,T2> void printInfo(T t, T2 t2) { // 泛型方法重载
		System.out.println(t);
		System.out.println(t2);
//		System.out.println(t1+t1); 方法类型不确定 不能加
	}
	
	public static <T extends Animal>void printfnfo2(T t) { 
		t.eat();
	}
}


public class Test {
	public static void main(String[] args) {
		A<Integer> a = new A<Integer>(); // 只能输出一种类型
		a.printInfo3(100);
//		a.printInfo3("ssa"); 
		
		D d = new D();  // 输出任意类型 更加灵活
		d.printInfo("哈哈");
		d.printInfo(124);
		d.printInfo(0.2);
		d.printInfo('a');
		d.printInfo("linruimiao", 100);
		
		
		D.printfnfo2(new Dog()); //施加类型约束的方法为静态方法,只能将其定义为泛型方法,因为静态方法不能使用其所在类的类型约束
		D.printfnfo2(new Person());
		D.printfnfo2(new Cat());
	
	
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值