------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
自学Java第五天笔记。本人是根据毕向东老师的JavaSE视频学习的。Java多态、内部类、异常、包
一.多态(面向对象特征之一)。
1.多态定义:可以理解为事物存在的多种体现形式。将对象调用变简单。
例:动物中猫,狗。猫这个对象对应的类型是猫类型,如:猫 x = new 猫(); 同时猫也是动物中的一种,也可以把猫称为动物。动物 y = new 猫(); 那么动物就是猫和狗具体事物中抽取出来的父类型。父类型引用指向了子类对象。
2.多态体现:父类的引用指向或接收自己的子类对象。
3.多态前提:
1)、必须是类与类之间有关系,继承或实现。
2)、存在覆盖。(父类中有方法被子类重写)
4.多态利弊:
好处:提高程序的扩展性。
弊端:当父类引用指向子类对象时Animal a = new Cat();,虽然提高了扩展性,但是只能访问父类中具备的方法,不可以访问子类中特有的方法,只能访问父类的方法或参数。
5.类型转换:我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。多态自始至终都是子类对象在做着变化。
例子(代码):
abstract class Animal
{
public abstract void eat();
}
class Cat extends Animal
{
public void eat()
{
System.out.println("吃鱼");
}
public static void catchMouse()
{
System.out.println("抓老鼠");
}
}
class DuoTai
{
public static void main(String[] args)
{
Animal a = new Cat();//类型提升,向上转型。
a.eat();
//如果要调用猫的特有方法,强制将父类引用,转成子类类型,向下转型
Cat c = (Cat)a;
c.catchMouse();
}
}
6.如果想用子类对象的特有方法,如何判断对象是哪个具体的子类类型呢?关键字 instanceof :判断指向的对象到底符合什么类型时。
7.多态应用:
例子(代码):
//将基础班和高级班这两类事物进行抽取。
abstract class Student
{
public abstract void study();
public void sleep()
{
System.out.println("躺着睡");
}
}
class BaseStudent extends Student
{
public void study()
{
System.out.println("基础学习");
}
public void sleep()
{
System.out.println("坐着睡");
}
}
class AdvStudent extends Student
{
public void study()
{
System.out.println("高级学习");
}
}
class DoStudent
{
public void doSome(Student stu)
{
stu.study();
stu.sleep();
}
}
class DuoTaiTest
{
public static void main(String[] args)
{
DoStudent ds = new DoStudent();
ds.doSome(new BaseStudent());
ds.doSome(new AdvStudent());
}
}
8.多态特点:
1)、在多态中成员函数的特点:
在编译时期:参考引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有,编译失败。
在运行时期:参考的是对象所属的类中是否有调用的方法。
简单一句:成员函数,编译看引用型变量所属的类(父类),运行看对象所属的类(子类)。更简单:成员函数编译看左边,运行看右边。
2)、在多态中成员变量的特点:
无论编译和运行,都参考左边(引用性变量所属的类)。
3)、在多态中静态成员函数的特点:
无论编译和运行,都参考左边。
9.Object:
1)、理解;所有类的直接或者间接父类(传说中的上帝),Java认为所有的对象都具备一些基本的共性内容,这些内容可以不断的向上抽取,最终就抽取到了一个最顶层的类中的,该类中定义的就是所有对象都具备的功能。
2)、具体用法(4个):(注意:Object类还有几个其他具体方法,后面视频中会学习到。)
1、boolean equals(Object obj):用于比较两个对象是否相等,其实内部比较的就是两个对象地址。而根据对象的属性不同,判断对象是否相同的具体内容也不一样。所以在定义类时,一般都会复写equals方法,建立本类特有的判断对象是否相同的依据。
例如: public boolean equals(Object obj){
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.age == p.age;
}
2、String toString():将对象变成字符串。默认返回的格式:类名@哈希值 = getClass().getName() + '@' + Integer.toHexString(hashCode()) 。
为了对象对应的字符串内容有意义,可以通过复写,建立该类对象自己特有的字符串表现形式。
例如: public String toString(){
return "person : "+age;
}
二.内部类。
1.内部类的访问规则:
1)、内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式:外部类名.this
2)、外部类要访问内部类,必须建立内部类对象。
2.内部类的访问格式:
1)、当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中,可以直接建立内部类对象。
格式:外部类.内部类名 变量名 = 外部类对象.内部类对象;
例如:Outer.Inter in = new Outer().new Inter();
当内部类在成员位置上,就可以被成员修饰符所修饰。
比如:
private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。当内部类被static修饰后,只能直接访问外部类中的static成员,出现访问局限。
在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inter().function();
在外部其他类中,如何直接访问static内部类的静态成员呢?
Outer.Inter.function();
注意:
当内部类中定义了静态成员,该内部类必须是静态的。
当外部类中的静态方法访问内部类时,内部类也必须静态。
2)、当内部类定义在局部时:
1、不可以被成员修饰符修饰。
2、可以直接访问外部类中的成员,因为还持有外部类的引用。但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量。
3.内部类理解与应用:将一个类定义在另一个类的里面,对里面那个类就称为内部类。当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事物在使用外部事物的内容。
4.匿名内部类:
1)、匿名内部类其实就是内部类的简写格式。
2)、定义匿名内部类的前提:内部类必须是继承一个类或者实现接口。
3)、匿名内部类格式:new 父类或者接口(){定义子类的内容}
4)、其实匿名内部类就是一个匿名子类对象。可以理解为带内容的对象。
5)、匿名内部类中定义的方法最好不要定义超过3个。
5.匿名内部类例子(代码):
abstract class AbsDemo
{
abstract void show();
}
class Outer
{
int x = 3;
/*
class Inner extends AbsDemo
{
void show()
{
System.out.println("show:"+x);
}
}
*/
public void function()
{
//new Inner().show();
new AbsDemo()
{
void show()
{
System.out.println("x==="+x);
}
}.show();
}
}
class NiMing
{
public static void main(String[] args)
{
new Outer().function();
}
}
6.匿名内部类练习(代码):
interface Inter
{
void method();
}
class Test
{
static Inter function()
{
return new Inter()
{
public void method()
{
System.out.println("匿名内部类练习");
}
};
}
}
class NiMingTest
{
public static void main(String[] args)
{
/*
Test.function():Test类中有一个静态方法function。
.method():function这个方法运算后结果是一个对象,而且是Inner类型对象。
因为只有是Inner类型的对象,才可以调用method方法。
*/
Test.function().method();
}
}
三.异常。
1.异常:就是程序在运行时出现不正常情况。(异常是对问题的描述,将问题进行对象的封装)
2.异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。其实就是java对不正常情况进行描述后的对象体现。
3.问题划分:
1)、一种是严重的问题。对于严重的问题,java通过Error类进行描述。对Error类一般不编写针对性的代码对其进行处理。
2)、一种是非严重的问题。对于非严重的,java通过Exception类进行描述。对于Exception可以使用针对性的处理方式进行处理。
Throwable:可抛出的。
1)、Error:错误,一般情况下,不编写针对性的代码进行处理,通常是jvm发生的,需要对程序进行修正。
2)、Exception:异常,可以有针对性的处理方式。
4.异常分两种:
1)、编译时被检查的异常,只要是Exception及其子类都是编译时被检测的异常。
2)、运行时异常,其中Exception有一个特殊的子类RuntimeException,以及RuntimeException的子类是运行异常,也就说这个异常是编译时不被检查的异常。
5.异常处理:
处理方式有两种:1)、捕捉;2)、抛出(throws)。
对于捕捉:java有针对性的语句块进行处理。
try {
需要被检测的代码;
}
catch(异常类 变量名){
异常处理代码;
}
fianlly{
一定会执行的代码;
}
有三个结合格式:
a、try
{
}
catch ()
{
}
b、try
{
}
finally
{
}
c、try
{
}
catch ()
{
}
finally
{
}
注意:
catch (Exception e) { //e用于接收try检测到的异常对象。
System.out.println("message:"+e.getMessage());//获取的是异常的信息。
System.out.println("toString:"+e.toString());//获取的是异常的名字+异常的信息。
e.printStackTrace();//打印异常在堆栈中信息;异常名称+异常信息+异常的位置。
}
finally:定义一定执行的代码。通常用于关闭资源。因为资源必须释放。finally只有一种情况不会执行,当执行到System.exit(0);finally不会执行。
6.异常体系的特点:异常体系中的所有类以及建立的对象都具备可抛性。也就是说可以被throw和throws关键字操作。只有异常体系具备这个特点。
throw和throws的用法:throw定义在函数内,用于抛出异常对象。throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。
当函数内容有throw抛出异常对象,并未进行try处理。必须要在函数上声明,否则编译失败。注意:RuntimeException除外。也就是说,函数内如果抛出RuntimeException异常,函数上可以不用声明。
7.多异常处理:
1)、声明异常时,建议声明更为具体的异常,这样处理的可以更具体。
2)、对方声明几个异常,就对应几个catch块。
如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面。
8.自定义异常:
1)、定义:当开发时,项目中出现了java中没有定义过的问题时,这时就需要我们按照java异常建立思想,将项目的中的特有问题也进行对象的封装。
2)、如何自定义异常:
定义类继承Exception或者RuntimeException;通过throw 或者throws进行操作。
为了让自定义类具备可抛性;让该类具备操作异常的共性方法。
当要定义自定义异常的信息时,可以使用父类已经定义好的功能。
将异常信息传递给父类的构造函数。
class MyException extends Exception
{
MyException(String message)
{
super(message);
}
}
9.当异常出现后,在子父类进行覆盖时,有了一些新的特点:
1)、当子类覆盖父类的方法时,如果父类的方法抛出了异常,那么子类的方法要么不抛出异常要么抛出父类异常或者该异常的子类,不能抛出其他异常。
2)、如果父类抛出了多个异常,那么子类在覆盖时只能抛出父类的异常的子集。
3)、如果父类或者接口中的方法没有抛出过异常,那么子类是不可以抛出异常的,如果子类的覆盖的方法中出现了异常,只能try不能throws。
如果这个异常子类无法处理,已经影响了子类方法的具体运算,这时可以在子类方法中,通过throw抛出RuntimeException异常或者其子类,这样,子类的方法上是不需要throws声明的。
10.异常的好处:
1)、将问题进行封装。
2)、将正常流程代码和问题处理代码相分离,方便于阅读。
11.异常练习:
class NoValueException extends RuntimeException //Exception
{
NoValueException(String message)
{
super(message);
}
}
interface Shape
{
void getArea();
}
class Circle implements Shape
{
private int radius;
public static final double PI = 3.14;//全局变量
Circle(int radius) //throws NoValueException
{
if(radius<=0)
throw new NoValueException("非法");
this.radius = radius;
}
public void getArea()
{
System.out.println(radius*radius*PI);
}
}
class YiChang
{
public static void main(String[] args)
{
/*
try
{
Circle c = new Circle(-2);
c.getArea();
}
catch (NoValueException e)
{
System.out.println(e.toString());
}
*/
Circle c = new Circle(-2);
c.getArea();
System.out.println("over");
}
}
四.包。
1.package理解:(定义包用package关键字)
在java中,管叫包,相当于文件夹。包里通常存放的是类文件,因为我们在编写程序的时候,难免会有类名相同的情况,就如我们人名一样。为了对类进行分类管理,java就有了包的出现,在不同包中可以有相同的类名,调用的时候连同包名一起就行。包也是一种封装形式。在包中可以有很多类文件,但是只提供一个类文件,供外界使用。
2.包作用:
对类文件进行分类管理,给类提供多层命名空间。包的出现可以将java的类文件和源文件相分离。
3.包规则:
包必须写在程序的第一行。
类的全名称是 包名.类名。
编译命令:javac –d 位置(.当前路径) java源文件 (就可以自动生成包)
4.包之间的访问:
1)、要访问其他包中的类,需要定义类的全称:包名.类名。
2)、包如果不在当前路径,需要使用classpath设定环境变量,为JVM指明路径。
3)、被访问的包中的类以及类中成员权限必须是public的。(注:一个.java文件里面,不能出现两个以上的公有类或者接口)
4)、类中的成员权限:public或者protected。protected是为其他包中的子类提供的一种权限。类公有后,被访问的成员也要公有才可以被访问。不同包中的子类可以直接访问父类中被protected权限修饰的成员。同一个包中,protected只作用为覆盖。
5.总结java中的四种权限:
范围 public protected default private
同一个类中 ok ok ok ok
同一包中 ok ok ok
子类 ok ok
不同包中 ok6.包的导入import:(简化书写)
类名称变长,写起来很麻烦。为了简化,使用了一个关键字:import,可以使用这个关键字导入指定包中的类。记住:实际开发时,到的哪个类就导入哪个类,不建议使用*.
import packa.*;这个仅仅是导入了packa当前目录下的所有的类。不包含子包。
import packa.abc.*;导入了packa包中的子包abc下的当前的所有类。
如果导入的两个包中存在着相同名称的类。这时如果用到该类,必须在代码中指定包名。
7.jar包:
1)、类越来越多,我们可以用包来装,当包越来越多时,我们可以将包进行压缩。而java中用jar这个工具来对包进行压缩。压缩后的后缀名为jar。
2)、jar :java的压缩包,主要用于存储类文件,或者配置文件等。
命令格式:jar –cf 包名.jar 包目录
解压缩:jar –xvf 包名.jar
将jar包目录列表重定向到一个文件中:jar –tf 包名.jar >c:\1.txt
3)、常见的软件包:
java.lang : language java的核心包,Object System String Throwable jdk1.2版本后,该包中的类自动被导入。
java.awt : 定义的都是用于java图形界面开发的对象。
javax.swing: 提供所有的windows桌面应用程序包括的控件,比如:Frame , Dialog, Table, List 等等,就是java的图形界面库。
java.net : 用于java网络编程方面的对象都在该包中。
java.io : input output 用于操作设备上数据的对象都在该包中。比如:读取硬盘数据,往硬盘写入数据。
java.util : java的工具包,时间对象,集合框架。