-----------android培训、java培训、java学习型技术博客、期待与您交流!------------
黑马程序员——45,内部类,多态,异常
一:一般内部类----》
一般内部类的介绍与例子,其中静态内部类与非静态内部类的区别是:只要有内部类中有静态成员,那么该内部类就是静态内部类。
class Person //外部类
{
private int x=10;
static int y=12;
private class Xinzang//非静态内部类,内部类可以被私有修饰
//如果内部类被私有修饰之后,外部类调用时还是可以建立内部类的对象
{
void function()
{
System.out.println("人类心脏跳动"+x);
//非静态内部类可以直接访问外部类成员(包括外部类私有成员)
//这句话打印的是“人类心脏跳动10”
}
}
static class Shenzang//静态内部类
//静态内部类中既可以定义静态成员,又可以定义非静态成员
{
void function()
{
//System.out.println(x);//静态内部类不能访问外部类的非静态成员
System.out.println("人的肾脏循环"+y);//静态内部类可以访问外部类的静态成员
}
}
void method()
{
Xinzang a=new Xinzang();//外部类的方法要访问内部类成员,先要建立内部类对象
a.function();
Shenzang b=new Shenzang();
b.function();
}
}
class Animal //动物类
{
private int x=50;
class Xinzang //动物类里面也有一个心脏类
{
void function()
{
System.out.println("动物心脏跳动"+x);
}
}
void method()
{
Xinzang a=new Xinzang();
a.function();
}
}
class Bird//鸟类
{
private int y=16;
class Xinzang //鸟类中的心脏类
{
int y=17;
void function()
{
//关于内部类的访问层次问题
int y=18;
System.out.println("鸟的心脏跳动"+y);
//打印的是“鸟的心脏跳动18”
System.out.println("鸟的心脏跳动+this"+this.y);
//打印的是“鸟的心脏跳动+this17”
System.out.println("鸟的心脏跳动+Bird.this"+Bird.this.y);
//打印的是“鸟的心脏跳动+Bird.this16”
}
}
void method()
{
Xinzang a=new Xinzang();
a.function();
}
}
class Neibulei//其他类
{
public static void main(String[] args)
{
Person ren=new Person();
ren.method();
Animal.Xinzang s=new Animal().new Xinzang();
/*
在其他类直接访问内部类时,引用型变量前面要写全称
而且后面既要新建外部类对象又要新建内部类对象。
*/
s.function();
/*Person.Xinzangs2=newPerson().new Xinzang();
如果内部类被私有化了就不能在其他类直接访问,否则编译出问题
*/
Bird s3=new Bird();
s3.method();
System.out.println("HelloWorld!");
}
}
二:局部内部类----》
局部内部类就是外部类中的某一个方法中的局部成员。对于局部内部类,因为static只能够修饰成员变量和成员方法,所以,局部内部类不能够被静态化,所以要保证局部内部类中不能有静态成员。在局部内部类所在的方法内,局部内部类只能访问带有final修饰的局部变量。
/*
内部类的一些小知识点
以下是讨论局部的内部类
*/
classPerson //外部类
{
int cishu=12;
void method(final int ji)//ji是method方法的局部变量
/*
为什么这里可以用final修饰ji呢?
因为method方法在栈内存中每执行一次就会释放消失,
执行过程中ji被锁定,执行完一次后method被释放,
第二次method被调用,接收的ji被锁定,这和第一次接收的ji的值不一致也没有关系
*/
{
//ji++;这句话编译不通过,因为接收过来的ji被锁定了,不可以更改
int cishu =13;
final int ji2=23;//ji2也是method方法的局部变量
class Xinzang
//类成员的内部类,因为static只能够修饰成员变量和成员方法,
//所以局部内部类不可以静态化
{
int cishu =14;
/*
static void function1(){}
内部类中存在静态成员,该内部类就是静态的,
但是这个Xinzang类是类成员的内部类,不能被静态化,
所以,static void function1(){}不能静态化
*/
void function()
{
//局部内部类中的访问层次问题
int cishu =15;
System.out.println("人类的心脏跳动+"+cishu);
//这句话打印的是“人类的心脏跳动+15”
System.out.println("人类的心脏跳动+this"+this.cishu);
//这句话打印的是“人类的心脏跳动+this14”
System.out.println("人类的心脏跳动+Person.this"+Person.this.cishu);
//这句话打印的是“人类的心脏跳动+Person.this12”
}
}
class Shenzang//肾脏类,也是类成员的内部类
{
void function()
{
System.out.println("打印的是ji_"+ji);
System.out.println("打印的是ji2_"+ji2);
//局部内部类只可以访问带有final修饰的所在局部的局部变量
}
}
new Xinzang().function();//匿名对象一次调用Xinzang类
new Shenzang().function();
}
}
class Neibulei2 //其他类
{
public static void main(String[] args)//主函数
{
Person a=new Person();
a.method(78);
System.out.println("HelloWorld!");
}
}
三:匿名内部类----》
匿名内部类其实就是带有内容的子类实例。接口可以看做是抽象类,所以对于所有的抽象类,都是可以用匿名内部类来使用的,只需要覆盖抽象类中全部的抽象方法即可。
/*
匿名内部类的一些介绍
*/
abstract class Xinzang//抽象的心脏类
{
public abstract void method();
}
interface Shenzang//肾脏接口
{
public abstract void method();
}
class Niming
{
public static void main(String[] args)//主函数
{
Xinzang a=new Xinzang(){
public void method()
{
Syatem.out.println("心脏在跳动");
}
};//直接在一个大括号里面实现抽象的心脏类,这就是匿名内部类
//这种形式就是匿名内部类,匿名内部类实际可以理解为带内容的子类对象
a.method();
new Xinzang(){
public void method()
{
Syatem.out.println("心脏在跳动");
}
}.method;
newShenzang(){
public void method()
{
System.out.println("肾脏处问题了");
}
}.method;
//接口就是特殊的抽象类,所以,在匿名内部类的写法上都是相同的
System.out.println("HelloWorld!");
}
}
四:多态----》
多态,就是事物的多种描述形式。
/*
关于多态的介绍
多态:事物的多种体现形式
动物:猫,狗
Cat a=new Cat();
Dongwu a=new Dongwu();
*/
abstract class Person/*人类*/
{
public abstract void eat();
}
class Student /*学生类*/ extends Person
{
public void eat()
{
System.out.println("学生吃东西");
}
public void study()
{
System.out.println("学生学习");
}
}
class Teacher /*教师类*/ extends Person
{
public void eat()
{
System.out.println("老师吃东西");
}
public void sleep()
{
System.out.println("老师睡觉");
}
}
class Duotai
{
public static void main(String[] args)//主函数
{
Person a= new Student();//父类的引用指向子类对象,向上转型
a.eat();
//a.study();这句话编译不通过,因为父类引用不能直接调用父类没有的方法
method(new Student());//父类引用也可以接收子类对象
//这种方式提高了程序的扩展性
method(newTeacher());
System.out.println("__________");
Personb=new Student();
method(b);
}
public static void method(Person b)//之所以要静态化,是因为静态只可以调用静态
{
b.eat();
if(b instanceof Student)//判断b是否是Student类
{
Student c=(Student)b;//向下转型,这样的话就可以调用子类的方法
c.study();
}
}
}
/*
多态中非静态成员函数与静态成员函数的特点
*/
class Animal//动物类
{
void shout()非静态方法
{
System.out.println("动物在叫");
}
void eat()//非静态方法
{
System.out.println("动物吃东西");
}
static void huxi()//静态方法
{
System.out.println("动物在呼吸");
}
}
class Cat /*猫类*/ extends Animal
{
void eat()
{
System.out.println("猫在吃鱼");
}
void sleep()
{
System.out.println("猫在睡觉");
}
static void huxi()//静态方法
{
System.out.println("猫在呼吸");
}
}
class Duotai2
{
public static void main(String[] args)//主函数
{
Animal a=new Cat();
a.eat();
a.shout();
//a.sleep();这句话编译不通过,因为在父类中没有sleep方法
/*
多态中非静态成员函数特点:
编译时候,看引用型变量所属的类中有调用的方法就通过
运行时候,看对象有调用方法就执行
*/
a.huxi();//这句话编译运行的结果是“动物在呼吸”
/*
这说明多态中,静态方法的编译和运行看引用型变量所属的类中有调用的方法就通过
*/
System.out.println("HelloWorld!");
}
}
五:异常----》
异常:程序运行时遇到的问题。
一般情况下,程序遇到的问题分为两种:
严重的Error(错误)这一类就难以解决了。
非严重Exception(异常)这一类是程序员主要应对的问题。
/*
异常的处理方式:
try
{
被检测的代码;
}
catch (异常类 变量)
{
针对异常的处理方式;
}
finally
{
一定执行的语句;
}
String getMessage();这个是异常类里面常用来获取异常信息的方法
以下举例是一个除0的例子。
*/
class Chufa//除法类
{
int cf(int x,int y)
{
return x/y;
}
}
class Yichang//自己定义的异常类(汉语拼音)
{
public static void main(String[]args)
{
Chufa a=new Chufa();//建立Chufa类的对象
try
{
int z=a.cf(15,0);//直接调用cf方法
System.out.println("没有问题");
}
catch (Exception e)
{
System.out.println("除数为0啦!!!");
}
finally
{
System.out.println("这是finally模块运行的结果");
}
System.out.println("哈哈");
//System.out.println("结果是"+z);
//这句话放在这里编译会出问题,因为z由于前面编译出问题没有给出确切值
}
}
当然,如果不想处理异常,可以在产生异常的方法上用throws声明。
class Chufa//除法类
{
int cf(int x,inty) throws Exception//声明该方法可能有问题
/*
因为声明了该方法可能有问题,
所以调用该方法的时候要么扑捉异常要么抛出异常
*/
{
return x/y;
}
}
class Yichang2//自己定义的异常类(汉语拼音)
{
public static void main(String[]args) throws Exception//把异常抛给了虚拟机
{
Chufa a=new Chufa();//建立Chufa类的对象
intz=a.cf(15,0);//直接调用cf方法
/*
如果是int z=a.cf(15,0);那就出了异常,
那么主函数又把异常抛给了虚拟机
相当于异常对象一次又一次的被往外面抛出去
*/
System.out.println("结果是"+z);
}
}
当然也可以声明多个异常:
class Chufa//除法类
{
int cf(int x,int y) throws ArithmeticException,ArrayIndexOutOfBoundsException
//声明了多个异常
{
int[] a= newint[x];
System.out.println(a[x]);
return x/y;
}
}
class Yichang3
{
public static void main(String[]args)
{
Chufa k=new Chufa();
try
{
int daan=k.cf(4,0);
System.out.println("除法结果是"+daan);
}
catch(ArithmeticException e )//处理除数为0的异常
{
System.out.println("除数为0");
}
catch (ArrayIndexOutOfBoundsException e)//处理角标越界的异常
{
System.out.println("数组角标越界了");
}
System.out.println("Hello World!");
}
}
当一个程序中有多个catch块的时候,就意味着有需要处理不同的异常,所以,一旦程序执行出现第一个异常的时候就会跳到处理第一个异常的catch块中执行对应操作,但是绝对不会同时执行两个catch块!
真正开发时候,catch块里面写的都是生成异常文件(日志),这是提供给网络维护员看的。
综合来看,Exception类和Error类都是Throwable类的子类,也只有Throwable类的体系才可以抛出。
另外,异常一般又分为运行时异常和非运行时异常,对于运行时异常RuntimeException一般不在方法上声明。
如果父类的方法抛出了异常,子类的覆盖方法只能够抛出父类异常或者父类异常的子类异常;如果父类抛出多个异常,子类覆盖方法只能抛出父类异常的子集;如果父类或者接口没有抛出异常,那么就算子类中产生异常也要在内部用try…catch…处理掉,不可以往外抛出。
-----------android培训、java培训、java学习型技术博客、期待与您交流!------------