(6)Java面向对象之加强篇

Java面向对象之加强篇

面向对象三大特征之多态

定义某一类事物存在的多种形态。

例如:动物中的猫,狗;人中的男人,女人;

猫对应的类型是猫类型;  猫 x = new ();

同时猫也是动物中的一种,也可以把猫称为动物。

动物 y = new ()

动物是猫和狗具体事物中抽取出来的父类型;

父类型引用指向了子类对象。

体现:父类或者接口的引用指向或者接受自己的子类对象。

作用:多态的存在提高了程序的扩展性和后期可维护性

前提:需要存在继承或者实现关系

   需要覆盖操作;

多态特点:

成员函数:编译时:要查看引用变量所属的类是否有所调用的成员;

  运行时:要查看对象所属的类中是否有所调用的成员

成员变量:只看引用变量所属的类。//面试考点

当静态方法或变量被覆盖一般面试题多,记住,父类走父类,子类走子类

多态的扩展性;

如代码:

abstract class Animal{
   abstract void eat();//定义一个抽象方法让其子类实现,这是多态前提
}
class Dog extends Animal{
	public void eat(){
		System.out.println(“啃骨头”);
  }
}
class Cat extends Animal{
	public void eat(){
		System.out.println(“吃鱼”);
	public void play(){
		System.out.println(“玩”);

  }
}
class DuoTaiDemo{
	public static void main(String[] args){
  function(new Cat());
  function(new Dog());
	}
	public static void function(Animal a){//接收所有动物的公有的吃的行为
a.eat();
  }
}//大大的提高了程序的扩展性;但是只能使用父类中的成员;

多态转型:

示例:

Animal a = new Cat();//类型提升,向上转型

a.eat();

//如果想要阿姨猫的特有方法时,怎么操作?

//可以强制将父类的引用转成子类类型,向下转型

Cat c = (Cat)a;//向下转型。

c.play();

注意:多态自始至终都是子类对象在做着变化!

小细节:当我们传进去的不是需要的类型就会报错,所以还需要对传进去的类型坐判断

如:

main 主函数

function(new Cat());

public static void function(Animal a){

if(a intanceof Animal)//判断是否是动物类型

{sop(“haha”);}

If(a intanceof Cat)//判断是否是猫类型

{ Cat c = (Cat)a;//向下转型。

c.play();

}

}

关于多态的具体应用示例:

基础班学生:

学习,睡觉。

高级班学生:

学习,睡觉。

可以将这两类事物进行抽取

代码实例:

abstract class Student{
	public abstract void study();
	public void sleep(){
		System.out.println("躺着睡");
	}
}
class DoStudent{//定义类接收共性内容传入类类型对象
	public void doSome(Student stu){
		stu.study();
		stu.sleep();
	}	
}
class BaseStudent extends Student{//基础班继承学生复写其方法
	public void study(){
		System.out.println("base study");
	}
	public void sleep(){
		 System.out.println("坐着睡");
	}
}
class AdvStudent extends Student{
	public void study(){
		System.out.println(" adv study");
	}
}
class  DuoTaiDemo{
	public static void main(String[] args) {
		DoStudent ds = new DoStudent();
		ds.doSome(new BaseStudent());//把子类对象作为参数传递给DoStudent
		ds.doSome(new AdvStudent());//这样可以优化代码,这就是多态的应用方面体现
}
练习多态: 多态主板示例:

/*
需求:
电脑运行实例,
电脑运行基于主板。
*/
interface PCI{//定义接口
	public void open();
	public void close();
}
class MainBoard{
	public void run(){
		System.out.println("mainboard run ");
	}
	public void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。{
		if(p!=null){//判断传进来是否一个null参数
			p.open();
			p.close();		
		}
	}
class NetCard implements PCI{//网卡实现接口复其写方法
	public void open(){
		System.out.println("netcard open");
	}
	public void close(){
		System.out.println("netcard close");
		method();
	}	
}
class SoundCard implements PCI{//声卡实现接口复写其方法
	public void open(){
		System.out.println("SoundCard open");
	}
	public void close(){
		System.out.println("SoundCard close");
	}
}
class DuoTaiDemo5 {
	public static void main(String[] args) {
		MainBoard mb = new MainBoard();//建立主板对象
		mb.usePCI(new NetCard());//主板对象调用其使用PCI接口方法,然后PCI接口作为引用指向了自己的子类对象,所以在里面直接new一个匿名的子类对象作为参数传进去
		mb.usePCI(new SoundCard());
		
	}
}

内部类:

就是讲一个类定义在另一个类里面,对里面的那个类称为内部类(内置类,嵌套类)

访问特点:

1, 内部类可以直接访问外部类中的成员,包括私有成员。

为什么呢?

因为内部类中持有了一个外部类的引用,格式是:外部类名.this 

2, 外部类要访问内部类,必须建立内部类对象。

格式:

外部类.内部类 变量名 外部类对象.内部类对象;

lass Outer{
	private int x = 3;
	private class Inner//内部类{
		void function(){
			System.out.println(x)//x前面省略了Outer.this.
		}
	void show(){
		Inner in = new Inner();
		In.function();
	}
}

3, 当内部类存在成员位置上,就可以被成员修饰符所修饰。

例如:

1private:将内部类在外部类中封装。

2Static:内部类就具备了静态的特性,他就只能访问外部类中的静态成员,有局限了

3,子啊外部其他类中,怎么直接访问静态内部类里面的非静态成员呢?

   这样访问:new Outer.Inner().function();

4,在外部其他类中,怎么直接访问static内部类的静态成员呢?

   这样访问:Outer.Inner().function();

注意:

当内部类中定义了静态成员,该内部类必须是静态的;

当外部类中的静态方法访问内部类,该内部类也必须是静态的

什么时候使用内部类

当描述事物时,事物内部还有事物,该事物用内部类来描述;

因为内部事物在使用外部事物的内容。如心脏在人身体内,心脏可以定义成内部类。

内部类定义在局部时:

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);// 访问被final修饰的局部变量
  			}
  		}
  		new Inner().function();	
  <span style="white-space:pre">	</span>}
  }

匿名内部类:

1,就是内部类简化写法。

2前提: 内部类可以继承或实现一个外部类或者接口

3格式: 

new 外部类名或者接口名(){

      复写类或者接口中的代码,也可以自定义内容;

}

简单理解就是:建立一个带内容的外部类或者接口的子类匿名对象。

bstract class AbsDemo{//先定义一个抽象类
	abstract void show();	
}
class Outer{
	int x = 3;
	public void function(){
		new AbsDemo(){//在成员方法里定义一个匿名内部类,因为没有名字所以只能用其父类名来标示,
  		void show(){/复写父类的方法
  			System.out.println(“匿名内部类”);/
  		void abc(){
  			System.out.println(“子类特有方法”);
  }.show();//调用其匿名内部类自己方法。
  }
		}
	}
}

思考:

AbsDemo d = new AbsDemo(){

Int num = 9;

void show(){

System.out.println(num);

};//这个怎么理解?

分析:

可能第一感觉是错误,抽象类怎么能建立对象?其实这是父类引用调用子类对象,AbsDemo d = new AbsDemo(){…};就等价于AbsDemo d = new Inner();

然后d调用其子类方法,d.show();但是对于子类特有方法abc();却是不能调用了,这个在多态时讲到了

练习:补足代码。通过匿名内部类。

nterface Inter{
	void method();
}
class Test {
	//补足代码区。
	Public static Inter function(){
		return new Inter(){
  		public void method(){
  			System.out.println(“run”);
  }
  };
	}
}
class InnerClassTest {
	public static void main(String[] args) {
		
		Test.function().method();//重点是看懂这段代码!		
//		Inter in = Test.function();
//		in.method();
		show(new Inter(){
			public void method(){
				System.out.println("method show run");
			}
		});
	}

分析:

Test.function().method()

//Test.function():Test类中有一个静态的方法function

//.method():function这个方法运算后的结果是一个对象。而且是一个Inter类型的对象。

//因为只有是Inter类型的对象,才可以调用method方法


面试题:

当没有给父类也没有接口还能写内部类吗?

分析:在main主函数里也是可以的,因为有“上帝“,是Object

<span style="font-size:18px;">lass InnerTest{
	public static void main(String[] args){
		new Object(){
			public void function(){
			System.out.println("上帝来了。");
			}
		}.function();
	}
}</span>

异常:

概述:

其实就是程序在运行时出现不正常情况。

异常由来:

 问题是现实生活中一个具体的事物,也可以通过Java的类的形式进行描述,并封装成对象。这个就是java对不正常情况进行描述后的对象体现。

异常体系:

对于问题划分:一个是严重的,一个是非严重的;

对于严重的:java通过Error类进行描述,一般不编写针对性的代码对其进行处理。

对于非严重的:java通过Exception类进行处理。在这里面可以使用针对性的处理

ErrorException的子类名都是以父类名作为后缀名

对于异常有很多种,我们可以查阅API文档java.lang包里面的Throwable(可抛)类,他是java语言中所有错误或异常的超类!

Throwable 中的常见方法:

1, getMessage();获取异常信息,返回字符串。

2, toString();获取异常名和信息,返回字符串

3, printStackTrace();获取异常类名和异常信息,以及异常出现在程序中的位置,返回值void

4, printStackTrace(PrintStream s)通常用该方法将异常内容保存在日志文件中,以便查阅

异常的处理格式:

try{

需要被检测的代码;

}

catch(异常类 变量){

处理异常的代码;处理方式

}

finally{

一定会被执行的语句;

}

异常声明:

throwthrows

throws用于标示函数暴露出的异常。

throw用于抛出异常对象。


区别和好处:

1, throws用在函数上,后面跟异常名;好处:便于提高安全性,让调用者进行处理,不处理就编译失败;

2, throw用在函数内,后面跟异常对象;


对多异常的处理。 

1,声明异常时,建议声明更为具体的异常。这样处理的可以更具体。

2,对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。

3,如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。


注意:

建立在进行catch处理时,catch中一定要定义具体处理方式。

不要简单定义一句 e.printStackTrace(),

也不要简单的就书写一条输出语句。

如下面例子:

关于在做除法时和数组角标越界出现的一些异常,怎么通过异常代码去解决

代码示例:

class Demo{
	int div(int a,int b)throws ArithmeticException,ArrayIndexOutOfBoundsException//在功能上通过throws的关键字声明了该功能有可能会出现问题。声明两个异常
	{
		int[] arr = new int[a];//
		System.out.println(arr[4]);
		return a/b;
	}
}
class  ExceptionDemo2{
	public static void main(String[] args) //throws Exception自己不处理又给抛出去
  {
		Demo d = new Demo();
		try{
			int x = d.div(5,0);
			System.out.println("x="+x);
		}
		catch (ArithmeticException e){
			System.out.println(e.toString());
			System.out.println("被零除了!!");
		}
		catch (ArrayIndexOutOfBoundsException e)	{
			System.out.println(e.toString());
			System.out.println("角标越界啦!!");
		}
		catch(Exception e){
			System.out.println("hahah:"+e.toString());
		System.out.println("over");
		}

	}
}

自定义异常

自定义类继承Exception或者其子类RuntimeExceeption

1, 为了让该自定义类具备可抛性

2, 让该类具备操作异常的共性方法。

因为父类中已经把异常信息的操作都完成了,所以子类在构造时,将异常信息传递给父类同过super语句就可以直接通过getMessage方法获取自定义异常信息。

通过构造函数定义异常信息。

例如:

class DemoException extends Exception{
  DemoException(String message){
		super(message);
	}
}

通过throw将自定义异常抛出。 

异常:RuntimeException

Exceptoin中有一个特殊的子类异常RuntimeException 运行时异常。

如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。

 

如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过;

对于异常分两种:

1,编译时被检测的异常。

1, 编译时不被检测的异常(运行时异常。RuntimeException以及其子类)

自定义异常时:

如果该异常的发生,无法再继续进行运算,就让自定义异常继承RuntimeException

示例:

lass FuShuException extends RuntimeException{
	FuShuException(String msg){
		super(msg);
	}
}
class Demo{
	int div(int a,int b)throws Exception//throws ArithmeticException{
		if(b<0)
			throw new FuShuException("出现了除数为负数了");//抛出自定义异常对象
		if(b==0)
			throw new ArithmeticException("被零除啦");//抛出RuntimeException的子类对象
		return a/b;
	}
}

异常练习题:

<span style="font-size:18px;">/*
需求:编写小程序 毕老师用电脑上课,在上课时会出现电脑蓝屏,冒烟现象
分析:
1,关于蓝屏冒烟这类异常需要我们自定义异常,继承Exception即可
2,对于电脑出现问题后也会导致老师无法上课,就需要将异常转换后再抛出和无法上课异常
3,描述毕老师定义变量,对于电脑也需要定义
步骤:
1,自定义蓝屏,冒烟,无法上课异常
2,定义电脑类,对其出现各种状况的进行异常处理
3,定义老师类,构造函数初始化内容
4,main函数处理老师不能教学的异常。

*/
class BlueException extends Exception//自定义蓝屏异常
{
	BlueException(String message)
	{
		super(message);
	}
}
class SmokingException extends Exception//自定义冒烟异常
{
	SmokingException(String message)
	{
		super(message);
	}
}
class NoTeachException extends Exception//自定义无法教学异常
{
	NoTeachException(String message)
	{
		super(message);
	}
}
class Computer//定义电脑类
{
	
	private int state = 2;//定义电脑状态
	public void run()throws BlueException,SmokingException//根据出现状态抛出了两个异常
	{	
		if (state==2)	
			throw new BlueException("电脑蓝屏了");
		if (state==3)
			throw new SmokingException("电脑冒烟了");
		System.out.println("在状态1,电脑正常运行");
	}	
	public void resetComputer()//重启电脑,状态恢复到1
	{
		state = 1;
		System.out.println("重启电脑");
	}
}
class Teacher
{
	private String name;
	private Computer cmp;
	Teacher(String name)
	{
		this.name = name;
		cmp = new Computer();//初始化
	}
	public void shangKe()throws NoTeachException
	{
		try
		{
			cmp.run();
		}
		catch (BlueException e)
		{
			cmp.resetComputer();
		}
		catch (SmokingException e)
		{
			ziXi();
			throw new NoTeachException("电脑坏了无法上课");//因为电脑坏了导致无法教学异常
		}
		System.out.println("在状态1时电脑正常上课");
	}
	public void ziXi()
	{
		System.out.println("自习");
	}
}
class LaoBiException
{
	public static void main(String[] args) 
	{
		Teacher t = new Teacher("毕老师");
		try
		{
			t.shangKe();
		}
		catch (NoTeachException e)
		{
			System.out.println("换一台电脑");
		}	
	}
}</span>
打印结果如图:


包(package)

1, 对类文件进行分类管理

2, 给类提供剁成命名空间

3, 卸载程序文件的第一行

4, 类名的全称是 包名.类名

5, 包也是一种封装形式。

具体特点:

包与包之间进行访问,被访问的包中的类以及类中成员,需要被public修饰。

不同包中的子类还可以直接访问父类中被protected权限修饰的成员

包与包之间可以使用的权限只有两种:

public protected.

现有权限总结如图:


Import (导入)

Import是简化类名

一个程序文件中只有一个package,可以有多个import

用来导包中的类,不导入包中的包

通常写import mypack.Demo

Jar

Java压缩包

通过jar.exe工具对jar的操作。

 

创建jar

Jar –cvf mypack.jar packa packb

查看jar

Jar –xvf mypack.jar

自定义jar包的清单文件

Jar –cvfm mypack.jar mf.txt packa packb


<pre>
 ---------------------- 
 ASP.Net+Android+IOS开发.Net培训、期待与您交流! ---------------------- 

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值