黑马程序员—【Java基础篇】之多态、内部类、异常及包


------- android培训 java培训 、期待与您交流! ---------

    大家好,这篇我们介绍和学习多态、内部类、异常和包的4大块知识点。

一、多态

1、定义

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

/**
例:动物中猫,狗。
猫这个对象对应的类型是猫类型
猫 x = new 猫();
同时猫也是动物中的一种,也可以把猫称为动物。
动物  y = new 猫();
动物是猫和狗具体事物中抽取出来的父类型。
父类型引用指向了子类对象。
*/

2、多态的体现 

/**
(1).程序中体现:父类或者接口的引用指向或者接收自己的子类对象。
(2).好处和作用:多态的存在提高了程序的扩展性和后期可维护性
(3).前提:需要存在继承或者实现关系;要有覆盖操作
*/

3、多态的特点

/**
成员函数:
1.编译时:要查看引用变量所属的类中是否有所调用的成员。
2.在运行时:要查看对象所属的类中是否有所调用的成员。
3.成员变量:只看引用变量所属的类。
*/
    多态小实例:
abstract class Animal  
{  
    public abstract void eat();  
  
}  
  
//子类————猫  
class Cat extends Animal  
{  
    //复写父类中的抽象功能  
    public void eat()  
    {  
        System.out.println("吃鱼");  
    }  
  
    //Cat特有的功能  
    public static void catchMouse()  
    {  
        System.out.println("抓老鼠");  
    }  
}  
  
  
class Demo  
{  
    public static void main(String[] args)   
    {  
        Animal a = new Cat(); //多态体现
        a.eat(); //编译看左边,运行看右边 
        Cat c = (Cat)a; //对a进行了强转 
        c.catchMouse();//调用cat类,catchMouse();方法 . 
    }  
}  

4、多态的应用

/*
需求:
电脑运行实例,
电脑运行基于主板。
*/


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)
		{
			p.open();//编译看接口,运行看子类。
			p.close();
			
		}
	}
}


class NetCard implements PCI
{
	public void open()
	{
		System.out.println("netcard open");
	}
	public void close()
	{
		System.out.println("netcard close");
		
	}
	
}
class SoundCard implements PCI
{
	public void open()
	{
		System.out.println("SoundCard open");
	}
	public void close()
	{
		System.out.println("SoundCard close");
	}
}
/*
class MainBoard
{
	public void run()
	{
		System.out.println("mainboard run");
	}
	public void useNetCard(NetCard c)
	{
		c.open();
		c.close();
	}
}

class NetCard
{
	public void open()
	{
		System.out.println("netcard open");
	}
	public void close()
	{
		System.out.println("netcard close");
	}
}
*/

class DuoTaiDemo5 
{
	public static void main(String[] args) 
	{
		MainBoard mb = new MainBoard();
		mb.run();
		mb.usePCI(null);
		mb.usePCI(new NetCard());
		mb.usePCI(new SoundCard());
		
	}
}

二、内部类

1、概念

<span style="font-size:12px;">/**
将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套类)。
访问特点:
内部类可以直接访问外部类中的成员,包括私有成员。
而外部类要访问内部类中的成员必须要建立内部类的对象。
*/</span>

2、位置

/**
1、成员位置
    可以被private static成员修饰符修饰。
    被static修饰的内部类只能访问外部类中的静态成员。
2、局部位置
    可以直接访问外部类中的成员。
    同时可以访问所在局部中的局部变量,但必须是被final修饰的。
*/

3、实例

/**
1.位置:内部类在局部位置上
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  InnerClassDemo  
{  
    public static void main(String[] args)   
    {  
        Outer out = new Outer();  
        out.method(7);//打印7  
        out.method(8);//打印8  
    }  
}  
/**
1.内部类位置在成员变量
class Outer
{
	private int x = 3;

	
	class Inner//内部类
	{
		//int x = 4;
		void function()
		{
			//int x = 6;
			System.out.println("innner :"+Outer.this.x);
		}
	}

	/**/
	void method()
	{
		Inner in = new Inner();
		in.function();
	}
}


class  InnerClassDemo
{
	public static void main(String[] args) 
	{
		Outer out = new Outer();
		out.method();

		//直接访问内部类中的成员。
//		Outer.Inner in = new Outer().new Inner();
//		in.function();
	}
}

4、规则

/**
一、内部类的访问规则:
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的。	
    当描述事物时,事物的内部还有事物,该事物用内部类来描述;因为内部事务在使用外部事物的内容。

5、内部类存在的必要

/**
    1、当描述事物时,事物的内部还有事物,则该事物使用内部类来描述,因为内部事物要使用外部事物内容。
    举例来说:楼房内部还有家庭住户,家庭住户中还有房间,这就可以用内部类描述。(比如需要访问一个楼房里的住户,就建立一个楼房对象吧,这样子的话,那是土豪的标志象征。)
    2、何时定义内部类
    当一个类需要直接访问另一个类中的成员时,则当这个类放入另一个类中,并将内部类封装。
    3、内部类生成文件
    我们在编译一个源文件是,如果代码中有内部类,你会发现,生成的class文件中含有例如这样的文件:A$C.class。这是为什么呢?因为内部类是一种编译现象,与虚拟机无关。编译器将会把内部类翻译成用$(美元符号)分隔外部类名和内部类名的常规类文件。 
*/

6、匿名内部类

(1)定义

    匿名是一种简写格式,是内部类的另一种书写方式。

    示例,如下:

/**匿名内部类:
interface Inter  //接口
{  
    void method(); //定义抽象方法 
}  
class InnerClassTest   //定义内部类
{  
    public static void main(String[] args)   
    {  
        show(new Inter() //匿名内部类 
        {  
            public void method()  //覆盖接口方法
            {  
                System.out.println("method show run");  
            }  
        });  
    }  
  
    public static void show(Inter in)  
    {  
        in.method();  
    }  
}  

(2)格式

/**
    匿名内部类的格式:
    new父类或者接口(){定义子类的内容}
*/

(3)前提条件

/**定义匿名内部类的前提:
     内部类必须是继承一个类或者实现接口。
     特殊情况:因为所以的类都有一个父类Object,所以在定义时也可以用Object。
      其实匿名内部类就是一个匿名子类对象。可以理解为带内容的对象。
      匿名内部类中定义的方法最好不要超过3个
*/

(4)利与弊

/**
匿名内部类的利与弊:
        好处:简化书写
        弊端:
             1、不能直接调用自己的特有方法、
             2、不能做强转动作。
             3、如果继承的父类或接口中有很多方法时,使用匿名内部类阅读性会非常差,且调用会很麻烦。所以匿名内部类中定义的方法有一般不超过3个。
*/

(5)何时定义

/**
    1、当使用的方法的参数类型是一个接口类型时,该接口的方法不超过3个,这时可以定义一个匿名内部类,把匿名内部类作为参数传进去。
    2、当没有父类和接口时,可以利用Object类创建匿名内部类。
*/

(6)练习

interface Inter  //接口
{     
    void method();  
}  
      
class Test  
{  
    //补足代码,通过匿名内部类  
}  
class InnerClassDemo   
{  
    public static void main(String[] args)   
    {  
            Test.function().method();     
}  
    }
/**分析:
       Test.function().method();//相当于Inter in=Test.function();in.method();
       Test.function():Test类中有一个静态的方法function。
      .method():function这个方法运算后的结果是一个对象,而且是一个Inter类型的对象。 因为只有是Inter类型的对象,才可以调用method方法。
*/
interface Inter  
{     
    void method();  
}  
  
class Test  
{  
    //补足代码,通过匿名内部类  
    static Inter function()  
    {     
        return new Inter()  
        {  
            public void method()  
            {  
                System.out.println("内部类练习");  
            }  
        };  
    }  
}  
  
class InnerClassDemo   
{  
    public static void main(String[] args)   
    {  
        Test.function().method();  
    }  
}  
    伙伴们这个例子,懂了木?那内部类的内容,我们就介绍到这里了,接下来,我们继续分享异常。

三、异常

1、理解

/**
 异常是Java中的重要机制,也使用了面向对象的思想,进行了封装。我们通常使用的异常类。
 异常类中所描述的就是程序中可能出现的错误或者问题。就像人生病一样,不一定经常有,但总有生病的时候,而且生病的原因不同,性质不同,对其的治疗自然也不一样。这些都可以在异常类中得以展现。
*/

2、概述

<pre name="code" class="java">/**
异常:就是程序在运行时出现不正常情况。
异常由来:
    问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述,并封装成对象;其实就是java对不正常情况进行描述后的对象体现。
    问题的划分:两种:一种是严重的问题,一种非严重的问题。
严重<span style="font-family: Arial, Helvetica, sans-serif;">问题</span><span style="font-family: Arial, Helvetica, sans-serif;">,java通过Error类进行描述。</span>
    对于Error一般不编写针对性的代码对其进行处理。
非严重的问题,java通过Exception类进行描述。
	对于Exception可以使用针对性的处理方式进行处理。
    无论Error或者Exception都具有一些共性内容。
    如:不正常情况的信息,引发原因等。
Throwable
	|--Error
	|--Exception
 
    

3、异常的处理

<span style="font-size:14px;">/**
异常的处理
java 提供了特有的语句进行处理。
try
{
	需要被检测的代码;
}
catch(异常类 变量)
{
	处理异常的代码;(处理方式)
}
finally
{
	一定会执行的语句;
}
*/</span><span style="font-size:18px;">
</span>

(1)异常处理的三种格式

<span style="font-size: 14px;"> </span><span style="font-size:14px;">/**
a、      try
            {
            }
             catch ()
             {
             }
b、       try
             {
             }
             finally
             {
             } 
c、	  try
             {
             }
             catch ()
             {
             }
             finally
             {
             } 
注意:  1)finally中定义的通常是关闭资源代码。因为资源必须释放。
        2)如果在一个功能中,定义了一些必须要执行的代码,可以用try{}finally{}的方式,将一定执行的代码放在finally代码块中。
        3)finally只有一种情况不会执行。当执行到System.exit(0);fianlly不会执行。</span><span style="font-size:18px;">
</span>

4、Throwable中的方法

/**
1、getMessage()
    获取异常信息,返回字符串。
2、toString()
    获取异常类名和异常信息,返回字符串。
3、printStackTrace()
    获取异常类名和异常信息,以及异常出现在程序中的位置。返回值void。
4、printStackTrace(PrintStream s)
    通常用该方法将异常内容保存在日志文件中,以便查阅。 
*/

5、异常练习

    示例1:

<span style="font-size:14px;">class Demo
{
	int div(int a,int b)throws Exception//在功能上通过throws的关键字声明了该功能有可能会出现问题。
	{
		return a/b;
	}
}
class  ExceptionDemo
{
	public static void main(String[] args) 
	{
		Demo d = new Demo();
		try
		{
			int x = d.div(4,1);
			System.out.println("x="+x);
		}
		catch (Exception e)//Exception e = new ArithmeticException();
		{
			System.out.println("除零啦");
			System.out.println(e.getMessage());//  / by zero;
			System.out.println(e.toString());// 异常名称 : 异常信息。

			e.printStackTrace();//异常名称,异常信息,异常出现的位置。
							//其实jvm默认的异常处理机制,就是在调用printStackTrace方法。
							//打印异常的堆栈的跟踪信息。
		}		
		System.out.println("over");

	}
}</span>
    示例2:
/**
需求:
毕老师用电脑上课。
考上课中出现的问题有:
	1、电脑蓝屏。
	2、电脑冒烟。
要对问题进行描述,封装成对象。

电脑冒烟后分享:可是当冒烟发生后,出现讲课进度无法继续。
第3个问题:出现了讲师的问题:课时计划无法完成。
*/

class LanPingException extends Exception//对问题进行描述,封装对象
{
	LanPingException(String message)
	{
		super(message);
	}
}
class MaoYanException extends Exception
{
	MaoYanException(String message)
	{
		super(message);
	}
}
class NoPlanException extends Exception
{
	NoPlanException(String msg)
	{
		super(msg);
	}
}

class Computer//对电脑描述,进行封装
{
	private int state = 3;
	public void run()throws LanPingException,MaoYanException
	{
		if(state==2)
			throw new LanPingException("蓝屏了");
		if(state==3)
			throw new MaoYanException("冒烟了");

		System.out.println("电脑运行");
	}
	public void reset()
	{
		state = 1;
		System.out.println("电脑重启");	
	}
}
class Teacher
{
	private String name;
	private Computer cmpt;

	Teacher(String name)
	{
		this.name = name;
		cmpt = new Computer();

	}

	public void prelect()throws NoPlanException
	{
		try
		{
			cmpt.run();			
		}
		catch (LanPingException e)
		{
			cmpt.reset();
		}
		catch (MaoYanException e)
		{
			
			test();
			throw new NoPlanException("课时无法继续"+e.getMessage());
			
		}
		System.out.println("讲课");
	}
	public void test()
	{
		System.out.println("练习");
	}

}


 
class ExceptionTest 
{
	public static void main(String[] args) 
	{
		Teacher t = new Teacher("毕老师");
		try
		{
			t.prelect();
		}
		catch (NoPlanException e)
		{
			System.out.println(e.toString());
			System.out.println("换老师或者放假");
		}
		
	}
}
/**
throws与throw的联系:
(1)throws用于标识函数暴露出的异常。
(2)throw用于抛出异常对象。
throws与throw的区别:
(1)thorws用在函数上,后面跟异常类名。
(2)throw用在函数内,后面跟异常对象。
*/
电脑蓝屏时,结果为:


当电脑起火时,结果为:


四、包

1、概述

/**
    java中的包就相当于系统中的文件夹。
    当我们需要将各个类分门别类的存放的时候,或者含有不同功能的相同类名的时候,需要用到包(package)。包可以将相关的类放在一起,并可以将两个或多个相同文件名的文件放在不同包中。
*/

2、作用

/**
    1、为避免多个类重名的情况,如果出现两个相同名字的类,可通过包将两者区分,从而避免冲突
    2、对类文件进行分类管理,可以将相关的一些类放在同一个包中。
    3、给类提供多层命名空间,如a包中的Demo.class文件即packagea.Demo.class
*/

3、规则

/**
    1、写在程序的第一行,因为是包下的类,先有包了,才能将类放进去。
    2、类名的全称:包名.类名
    3、包是一种封装形式,是java封装性的体现。
*/

4、包与包之间的访问

/**
    1、要访问其他包中的类,需要定义类名的全名:包名.类名
    2、如果包不再当前目录下,需要设置classpath,告知虚拟机包的执行路径
    3、有了包,范围变大,一个包中的类要被访问,必须有足够大的权限。
*/

5、注意事项

/**
    1.包与包间进行访问,被访问的包中的类以及类中的成员,需要public修饰。
    2.不同包中的子类还可直接访问父类中被protected权限修饰的成员。包与包间可使用的权限有两种:public和protected。
    3.其中protected只用于覆盖。
*/

6、示例

package pack;

/**
    为了简化类名的书写,使用一个关键字,import.
    import 导入的是包中的类。
    建议,不要写通配符 * ,需要用到包中的哪个类,就导入哪个类。
c:\myclass\packb\DemoA.class
c:\myclass\packb\haha\DemoZ.class
import packb.*;
import packb.haha.*;
    建立包名小技巧:建立定包名不要重复,可以使用url来完成定义,url是唯一的。
package cn.itcast.demo
package cn.itcast.test
*/

import packb.haha.hehe.heihei.*;
import packa.*;
import packb.*;
class  PackageDemo
{
	public static void main(String[] args) 
	{

		DemoC c = new DemoC();

//		packa.DemoA d = new packa.DemoA();
//		d.show();

//		packb.DemoB d = new packb.DemoB();
//		d.method();
	}
}
<pre name="code" class="java">/**
总结:
	包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰。
	不同包中的子类还可以直接访问父类中被protected权限修饰的成员。

包与包之间可以使用的权限只有两种,public  protected。
             public   protected       default     private
同一个类中     ok         ok             ok          ok
同一个包中     ok         ok             ok
子类           ok         ok             
不同包中       ok

java.lang : java的核心包 jdk1.2版本以后,该包中的类自动导入。
java.awt: 用于制作图形界面。
java.io:input output  用于操作设备上的数据。
java.util : 这里定义是java的工具类。集合,日期。
java.net:用于网络通讯的。
java.applet:  application  let        server  let    servlet      java server page   jsp  
class haha implements Servlet
class hehe extends HttpServlet
*/
     好了,伙伴们今天这篇就到这里了,下篇见。 
  




------- android培训 java培训 、期待与您交流! ---------

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值