Java面向对象--多态、异常

多态

定义:
某一类事物的多种存在形态,简单说就是一个对象对应着不同类型。例如动物中猫,狗。
猫这个对象对应的类型是猫类型:猫x=new猫(),同时猫也是动物中的一种,也可以把猫称为动物:动物y=new猫()。
动物是猫和狗具体事物中抽取出来的父类型,父类型引用指向了子类对象。
体现:
父类或者接口的引用指向或者接收自己的子类对象。
前提:
1.需要存在继承或者实现关系。
2.需要有覆盖操作。
好处:
提高了代码的扩展性,前期定义的代码可以使用后期的内容。
弊端:
前期定义的内容不能使用(调用)后期子类的特有内容。
/*
  动物多能吃,猫狗猪都是动物
*/
abstract class Animal {
	
	abstract void eat();
}

class Cat extends Animal {
	
	public void eat() {
		System.out.println("吃鱼");
	}
	public void catchMouse() {
		System.out.println("抓老鼠");
	}
}

class Dog extends Animal {
	
	public void eat() {
		System.out.println("吃骨头");
	}
	public void kanjia() {
		System.out.println("看家");
	}
}

class Pig extends Animal {
	
	public void eat() {
		System.out.println("饲料");
	}
	public void gongdi() {
		System.out.println("拱地");
	}
}

class DuoTaiDemo {

	public static void main(String[] args) {
		Animal a = new Cat();  //类型提升,向上转型
		a.eat();
		
		Cat c = (Cat)a;  //强制将父类的引用,转换成子类类型
		c.catchMouse();
	}

}
instanceof:用于判断对象的具体类型,只能用于引用数据类型判断,通常在向下转型前用于健壮性的判断。
public static void function(Animal a)//Animal a = new Cat();
	{
		a.eat();
		 
		if(a instanceof Cat)  //判断a是不是引用了Cat类型,如果是的话就向下转型,调用Cat里面的特有方法
		{
			Cat c = (Cat)a;
			c.catchMouse();
		}
		else if(a instanceof Dog)
		{
			Dog c = (Dog)a;
			c.kanJia();
		}


		 
	
	}

多态成员的特点:

成员函数
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是,成员函数在多态调用时,编译看左边,运行看右边。
成员变量
无论编译和运行,都参考左边(引用型变量所属的类)。
静态成员函数
无论编译和运行,都参考做左边。
class Fu
{
	static int num = 5;
	void method1()
	{
		System.out.println("fu method_1");
	}
	void method2()
	{
		System.out.println("fu method_2");
	}
	static void method4()
	{
		System.out.println("fu method_4");
	}
}


class Zi extends Fu
{
	static int num = 8;
	void method1()
	{
		System.out.println("zi method_1");
	}
	void method3()
	{
		System.out.println("zi method_3");
	}

	static void method4()
	{
		System.out.println("zi method_4");
	}
}
class  DuoTaiDemo4
{
	public static void main(String[] args) 
	{
		
		Fu f = new Zi();

		System.out.println(f.num);  //出现的是父类的num
<pre name="code" class="java">                f.method4();  //调用的是父类的方法
Zi z = new Zi();System.out.println(z.num); z.method4(); }}
 
 

内部类

定义:将一个类定义在另一个类的里面,里面那个类就称为内部类(内置类,嵌套类)。
访问特点:
内部类可以直接访问外部类中的成员,包括私有成员。而外部类要访问内部类中的成员必须要建立内部类的对象。
内部类定义在成员位置上,可以被private、static成员修饰符修饰。被static修饰的内部类只能访问外部类中的静态成员。
class Outer {
	private int num = 3;
	
	class Inner {
		void show() {
			System.out.println(num);
		}
	}
	
	public void method() {
		Inner in = new Inner();
		
		in.show();
	}
}

class InnerDemo {

	public static void main(String[] args) {
		
		Outer ou = new Outer();
		//Outer.Inner in = new Outer().new Inner();直接访问内部类
		
		ou.method();

	}

}

内部类的访问规则

1,内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
2,外部类要访问内部类,必须建立内部类对象。
访问格式:
1,当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。
可以直接建立内部类对象。
格式
外部类名.内部类名  变量名 = 外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();
2,当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
                在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();
                在外部其他类中,如何直接访问static内部类的静态成员呢?
uter.Inner.function();
 注意:当内部类中定义了静态成员,该内部类必须是static的。 当外部类中的静态方法访问内部类时,内部类也必须是static的。当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事务在使用外部事物的内容。
class InnerDemo1 {

	private static int num = 3;
	
	static class Inner1 {
		
		void show() {   //如果内部类成员也是静态的,就可以不用创建内部类对象直接调用  InnerDemo1.Inner1.show();
			System.out.println("show run ..."+num);
		}
		
	}

}

class InnerClassDemo1 {
	
	public static void main(String[] agrs) {
		
		InnerDemo1.Inner1 in = new InnerDemo1.Inner1();  //当内部类被static修饰时,就相当于一个外部类
		in.show();
	}
	
}

内部类定义在局部时

1,不可以被成员修饰符修饰
2,可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
class Outer
{
	int x = 3;

	void method(final int a)
	{
		final int y = 4;
		class Inner   //内部类定义在局部位置上
		{
			void function()
			{
				System.out.println(y);
			}
		}
	
		new Inner().function();
		
	}
}


class  InnerClassDemo3
{
	public static void main(String[] args) 
	{
		Outer out = new Outer();
		out.method(7);
		out.method(8);
	}

}

匿名内部类

概念:
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
3,匿名内部类的格式:  new 父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。 可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个。

异常

概念:是在运行时期发生的不正常情况,在java中用类的形式对不正常情况进行了描述和封装对象。描述不正常的情况的类,就称为异常类。
对于严重的问题,java通过Error类进行描述,对于Error一般不编写针对性的代码。对于非严重的问题,java通过Exception类进行描述,对于Exception可以使用针对性的处理方式进行处理。

Throwable

概念:无论error或者exception都具有一些共性内容,抽取出来的父类就是Throwable。无论是error,还是异常、问题,问题发生就应该可以抛出,让调用者知道并处理。
特点:Throwable及其所有的子类都具有可抛性。
可抛性:throwsthrow,凡是可以被这两个关键字所操作的类和对象都具备可抛性。
异常的处理,java提供了特有的语句进行处理
     try {
  需要被检测的代码;
     }
     catch(异常类 变量) {
  处理异常的代码:(处理方式)
     }
     finally {
  一定会执行的语句;
     }
便于提高安全性,让调用出进行处理,不处理则编译失败
Throwable中的方法
1.getMessage():获取异常信息,返回字符串。
2.toString():获取异常类名和异常信息,返回字符串。
3.printStackTrace():获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void。
4.printStackTrace(PrintStreams):通常用该方法将异常内容保存在日志文件中,以便查阅。
class Demo {
	
	int div(int a,int b)throws Exception {  //throws Exception表示在功能上通过throws的关键字声明了该功能有可能会出现问题
		return a/b;
	}
}

class ExceptionDemo1 {

	public static void main(String[] args) {
		Demo d = new Demo();
		try {
			int x = d.div(4, 0);
		}
		catch(Exception e) {
			System.out.println(e.getMessage()); //异常信息
			System.out.println(e.toString()); //异常名称:异常信息
			e.printStackTrace();  //异常名称,异常信息,异常出现的位置
		}

	}

}

对多异常的处理
1.声明异常时,建议声明更为具体的异常,这样处理的可以更具体
2.对方声明几个异常,就对应有几个catch块,不要那么定义多余的catch块。如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。建立在进行catch处理时,    catch中一定要定义具体处理方式,不要简单一句e.printStackTrace()
class Demo2 {
	
	int div(int a,int b) throws ArithmeticException,ArrayIndexOutOfBoundsException {
		int[] arr = new int[a];
		
		System.out.println(arr[4]);
		return a/b;
	}
	
}

class ExceptionDemo2 {

	public static void main(String[] args) {
		
		Demo2 d = new Demo2();
		
		try {
			int x = d.div(4, 1); 
			System.out.println("x="+x);
		}

                //调用的函数中声明了两个异常,所以必须用两个catch来处理
		catch(ArithmeticException e) {
			System.out.println(e.toString());
		}
		catch(ArrayIndexOutOfBoundsException e) {
			System.out.println(e.toString());
		}
		
		System.out.println("over");
		
	}

}

自定义异常

概述:
因为项目中会出现特有的问题,而这些问题并未被java所描述并封装对象。所以对于这些特有的问题可以按照java的对问题封装的思想,将特有的问题,进行自定义异常封装
自定义异常必须继承Exception,因为异常体系有一个特点,异常类和异常对象都被抛出,他们都具备可抛性,这个可抛性是Throwable这个体系中独有的特点,只有这个体系中的类和对象才可以被throws和throw操作
class FuShuException extends Exception {
	
	private int value;
	FuShuException(String mag,int value){
		super(mag);  //直接调用父类的构造方法来完成初始化
		
		this.value = value;
	}
	
	public int getValue() {
		return value;
	}
}

class Demo3 {
	
	int div(int a,int b)throws FuShuException {
		

             //通过throw将自定义异常抛出
		if(b < 0) {
			throw new FuShuException("出现了除数是负数的情况       /by fushu",b);   //手动通过throw关键字抛出一个自定义异常对象
		}
		
		return a/b;
	}
	
}

class ExceptionDemo3 {

	public static void main(String[] args) {
		
		Demo3 d = new Demo3();
		
		try {
			int x = d.div(4,-1);
			
			System.out.println(x);
		}
		catch(FuShuException e) {
			System.out.println(e.toString());
			System.out.println("出现负数:"+e.getValue());
		}

	}

}

注意:
当函数在内部出现了throw抛出异常对象,那么久必须要给对应的处理动作,要么在内部try catch处理,要么在函数上声明让调用者处理。一般情况在,函数内出现异常,函数上需要声明
throws和throw的区别
   throws使用在函数上,后面跟的是异常类,可以跟多个,用逗号隔开
   throw使用在函数内,后面跟的是异常对象

异常的分类

1.编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系。这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。    这样的问题都可以针对性的处理。
2.编译时不检测异常(运行时异常):就是Exception中的RuntimeException和其子类。这种问题的发生,无法让功能继续,运算无法运行,更多是因为调用的原因导致的或者    引发了内部状态的改变导致的。那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行调整。
class MinusException extends RuntimeException {
	
	MinusException(String meg) {
		super(meg);
	}
	
}

class Demo4 {
	
	int div(int a,int b) {
		if(b < 0 ) {
			throw  new MinusException("改程序被除数不能为负数");
		}
		return a/b;
	}
}

class ExceptionDemo4 {

	public static void main(String[] args) {
		
		Demo4 d = new Demo4();
		
		System.out.println(d.div(4,-1));
		
	}

}

finally:通常用来关闭资源。比如:数据库资源,IO资源等。
try catch finally代码块组合特点
1.try catch finally
2.try catch(多个):当没有资源需要释放时,可以不用定义finally。
3.try finally:异常无法直接catch处理,但是资源必须关闭。
注意:
1.子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的
2.如果父类抛出多个异常,那么子类只能抛出父类异常的子集。
    也就是说::子类覆盖父类只能抛出父类的异常或者子类的子集。
3.如果父类的方法没有抛出异常,那么子类覆盖时绝对不能抛,就只能try。

Object类

Object:所有类的根类,是不断抽取而来,具备着所有对象都具备的共性内容。
Object中的方法
equals():默认都是根据对象的哈希值判断两个对象是否相等。
toString():默认返回的内容是“对象所属的类名+@+对象的哈希值(十六进制)”。












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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值