面向对象
面向对象是相对面向过程而言,面向对象和面向过程都是一种思想。
面向过程:
强调的是功能行为。代表语言:C语言。
例子:把大象装进冰箱
1.打开冰箱。
2.存储大象。
3.关上冰箱。
"打开"、"存储"、"关上"都是功能行为,在代码中的直观体现就是函数或者方法,这就是一种面向过程的以功能行为为主体的思想体现。
面向对象:
将功能封装对象,强调具备了功能对象。代表语言:Java、C++、C#。
例子:把大象装进冰箱
1.冰箱打开。
2.冰箱存储。
3.冰箱关闭。
可以看到,所有的操作都是以"冰箱"为主体,而不是功能行为。也就是说冰箱自己已经具备"打开"、"存储"、"关上"的行为功能,我们只需要让冰箱执行它具备的功能就可以了。这就是一种面向对象的以执行功能的对象为主体的思想体现。
面向对象的特点
是一种符合人们思考习惯的思想,可以将复杂的事情简单化,将程序员从执行者转换成了指挥者。
完成需求时:
1.先要去找具有所需功能的对象来用。
2.如果该对象不存在,那么创建一个具有所需功能的对象。这样就可以简化开发并提高复用。
面向对象开发、设计、特征
开发过程:其实就是不断的创建对象、使用对象、指挥对象做事情。
设计过程:其实就是在管理和维护对象之间的关系。
面向对象的特征:封装(encapsulation)、继承(inheritance)、多态(polymorphism)
面向对象方式开发的软件系统,其最小的程序单元是类,这些类可以生成系统中的多个对象,而这些对象则直接映像成客观世界的各种事物。
类与对象之间的关系
使用计算机语言不断递在描述现实生活中的事物。java中描述事物通过类的形式体现,类是具体事物的抽象,概念上的定义。对象即是该类事物实实在在存在的个体。(如下图)
可以理解为:类就是图纸,汽车就是堆中内存中的对象。
类的定义
生活中描述的无非就是描述事物的属性和行为。如:人有身高,体重等属性,有说话,打球等行为。
属性:对应类中的成员变量。
行为:对应类中的成员函数。
/**
描述汽车
分析:
1.属性
轮胎数
行为
颜色
2.行为
运行
定义类其实就是定义类中的成员。
成员:成员变量<-->属性,成员函数<-->行为。
*/
class Car
{
//成员变量
/*
成员变量:
1.成员变量定义在类中,在整个类中都可以被访问。
2.成员变量随着对象的建立而建立,随着对象的消失而消失,存在于对象所在的堆内存中。
3.成员变量有默认初始化值。
*/
String color = "red";
int num = 4;
//成员方法
void show()
{
//临时变量 或 局部变量
/*
局部变量:
1.局部变量只定义在局部范围内,如:函数内,语句内等,只在所属的区域有效。
2.局部变量存在于栈内存中,作用的范围结束,变量空间会自动释放。
3.局部变量没有默认初始化值。
*/
int num = 10;
//输出临时变量的值
System.out.println("color ="+color+"...num"+num);
}
}
class CarDemo
{
//通过new关键字,建立对象 c就是一个类类型的引用变量,指向了该类的对象
Car c = new Car();
//对对象的属性进行修改
c.color = "black";
//输出成员变量的默认值
System.out.println(c.num);
//调用对象的功能 即方法
c.show();
}
对象内存结构
只要是用new操作的实体类就会在堆内存中开辟一个新的空间,并且每一个对象中都有一份属于自己的属性。
通过对象.对象中的成员的方式操作对象中的成员,对其中一个对象的成员进行了修改,和另一个对象没有任何关系。
需要提到的是c1、c2都是对实体的引用变量,如果执行c2=c1,那么c2也就指向了c1引用的实体。c2原来引用的实体因为没有被引用变量引用,就会被垃圾回收器回收。
匿名对象
匿名对象是对象的简化形式。
匿名对象两种使用情况
1.当对对象方法进行一次调用时。
2.匿名对象可以座位实际参数进行传递。
class CarDemo
{
public static void main(String[] args)
{
//对对象的一次调用时,就可以这样使用匿名对象
new Car().run();
//匿名对象可以作为实际参数进行传递
show(new Car());
public
}
public static void show(Car c)
{
System.out.println(c.num+"...."+c.color);
}
}
class Car
{
String color = "red";
int num = 4;
public void run()
{
System.out.println("run run run...")
}
}
封装
是指隐藏对象的属性和实现细节,仅对外提供公访问方式
好处:
1.将变化隔离。
2.便于使用。
3.提高重用性。
4.提高安全性。
封装原则:
1.将不需呀对外提供的内容都隐藏起来。
2.把属性都隐藏,提供公共方法对其访问。如,getXXX,setXXX.
class Person
{
//private:私有,是一个权限修饰符,用于修饰
//不希望别人直接访问赋值,需要通过私有化把属性进行隐藏
private int age ;
//通过提供set、get公共方法对其访问
public void setAge( int a)
{
//在set方法内可以对属性的赋值进行限制
if (a > 0 && a < 130)
{
age = a;
}
else
System.out .println("错误的数据" );
}
public int getAge()
{
return age ;
}
void speak()
{
System.out .println("age = " + age);
}
}
class PersonDemo
{
public static void main(String[] args)
{
Person p = new Person();
//通过公共方法去访问
p.setAge(20);
p.speak();
//赋值不合法,setAge方法不允许成功赋值
p.setAge(-20);
}
}
P.S.
1、私有仅仅是封装的一种体现而已。
2、private关键字:是一个权限修饰符,用于修饰成员(成员变量和成员函数),被私有化的成员只在本类中有效。
3、常用场景之一:将成员变量私有化,对外提供对应的set、get方法对其进行访问,提高对数据访问的安全性。
构造函数
特点:
1.函数名与类名相同。
2.不用定义返回值类型。
3.没有具体的返回值。
作用:给对象进行初始化
this关键字
this代表其所在函数所属对象的引用。换言之,this代本类对象的引用。当成员变量和局部变量重名,可以用关键字this来区分,this就是所在函数所属对象的引用。简单说,哪个对象调用了this所在的函数,this就代表哪个对象。一般方法调用默认加this。
什么时候使用this关键字呢?
当在函数内需要用到调用该函数的对象时,就用this。
static关键字
static关键字:用于修饰成员(成员变量和成员函数)。
被修饰后的成员具备以下特点:
1、随着类的加载而加载。
2、优先于对象存在。
3、被所有对象所共享。
4、可以直接被类名调用。
成员变量和静态变量的区别?
1.两个变量的生命周期不同
成员变量随着对象的创建而存在,随着对象被回收而释放。
静态变量随着类的加载而存在,随着类的消失而消失。
2.调用方式不同
成员变量只能被对象调用。
静态变量可以被对象调用,还可以被类名调用。
3.别名不同
成员变量也称为实例变量。
静态变量也称为类变量。
4.数据存储位置不同
成员变量存储在堆内存的对象中,所以也叫对象的特有数据。
静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据。
静态代码块
随着类的加载而执行,而且只执行一次。
作用:用于给类进行初始化。
class StaticCode
{
static int num;
static
{
num = 10;
}
static void show()
{
System.out.println(num);
}
}
class StaticCodeDemo
{
public static void main(String[] args)
{
StaticCode.show();
}
}
构造代码块
作用:可以给所有对象进行初始化。
class Demo1116
{
public static void main(String[] args)
{
Person p = new Person();
p.setAge(20);
p.speak();
/*
首先会执行Person代码块
再构造函数
执行方法
*/
}
}
class Person
{
//构造代码块
{
System.out.println("person run");
}
public Person(int age)
{
this.age = age;
System.out.println("gou zao");
}
private int age ;
void speak()
{
System.out .println("age = " + age);
}
}
单例设计模式
设计模式:对问题行之有效的解决方式,其实,它是一种思想。
单例设计模式解决的问题:就是可以保证一个类在内存中的对象唯一性。
比如多个程序使用同一个配置信息对象时,就需要保证该对象的唯一性。
如何保证对象唯一性呢?
1、不允许其他程序用new创建该类对象。
2、在该类创建一个本类实例。
3、对外提供一个方法让其他程序可以获取该对象。
步骤:
1、私有化该类构造函数。
2、通过new在本类中创建一个本类对象。
3、定义一个公有的方法,将创建的对象返回。
示例(饿汉式):
class Single
{
private static Single s = new Single();
private Single(){}
public static Single getInstance(){
return s;
}
}
class SingleDemo
{
public static void main(String[] args)
{
Single s1 = new Single.getInstance();
Single s2 = new Single.getInstance();
System.out.println(s1==s2);//true
}
}
示例(懒汉式):
class Single
{
private static Single s = null
private Single(){}
private static Object obj = new Object();
public static Single getInstance(){
if(s==null)
{
synchronized(obj)
{
if(s==null)
s=new Single();
}
}
return s;
}
}
class SingleDemo
{
public static void main(String[] args)
{
Single s1 = new Single.getInstance();
Single s2 = new Single.getInstance();
System.out.println(s1==s2);//true
}
}
继承
通过extends关键字让类与类之间产生继承关系。
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。多个类可以称为子类,单独这个类称为父类或者超类。
P.S.
1、子类可以直接访问父类中的非私有的属性和行为。
2、子类无法继承父类中私有的内容。
3、父类怎么来的?共性不断向上抽取而来的。
class Person
{
String name;
int age;
}
class Student extends Person
{
void study()
{
System.out.println("student study..."+age);
}
}
class Worker extends Person
{
void Work()
{
System.out.println("worker work..."+age);
}
}
class ExtendDemo
{
public static void main(String[] args)
{
Student s = new Student();
s.name = "zhangsan";
s.age = 20;
s.study();// student study...20
Worker w = new Worker();
w.name = "lisi";
w.age = 30;
w.work();//worker work...30
}
}
好处:
继承的出现提高了代码的复用性。
继承的出现让类与类之间产生了关系,提供了多态的前提。
继承的特点
Java只支持单继承,不支持多继承。
一个类只能有一个父类,不可以有多个父类。
原因:因为多继承容易出现问题。两个父类中有相同的方法,子类到底要执行哪一个是不确定的。
super关键字&函数覆盖
1.成员变量
this和super的用法很相似。
this代表本类对象的引用。
super代表父类的内存空间的标识。
当本类的成员和局部变量同名用this区分。
当子父类中的成员变量同名用super区分父类。
2.成员函数
当子父类中出现成员函数一模一样的情况,会运行子类的函数。
这种现象,称为覆盖操作,这是函数在子父类中的特性。
在子类覆盖方法中,继续使用被覆盖的方法可以通过super.函数名获取。
函数两个特性:
1.重载,同一个类中。
2.覆盖,子类中,覆盖也称为重写,覆写,override。
什么时候使用覆盖操作?
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以复写父类中的方法,这样,即沿袭了父类的功能,又定义了子类特有的内容。
P.S.
1、父类中的私有方法不可以被覆盖。
2、父类为static的方法无法覆盖。
3、覆盖时,子类方法权限一定要大于等于父类方法权限。
构造函数
子父类中构造函数的特点:
在子类构造函数执行时,发现父类构造函数也运行了。
原因:在子类的构造函数中,第一行有一个默认的隐式语句:super();。
总结:
一个对象实例化过程,以Person p = new Person();为例:
1. JVM会读取指定的路径下的Person.class文件,并加载进内存,并会先加载Person的父类(如果有直接的父类的情况下)。
2. 在内存中开辟空间,并分配地址。
3. 并在对象空间中,对对象的属性进行默认初始化。
4. 调用对应的构造函数进行初始化。
5. 在构造函数中,第一行会先到调用父类中构造函数进行初始化。
6. 父类初始化完毕后,再对子类的属性进行显示初始化。
7. 再进行子类构造函数的特定初始化。
8. 初始化完毕后,将地址值赋值给引用变量。
final关键字
final可以修饰类,方法,变量。
final修饰的类不可以被继承。
final修饰的方法不可以被覆盖。
final修饰的变量是一个常量,只能被赋值一次。
抽象类
抽象定义:
抽象就是从多个事物中将共性的、本质的内容抽取出来。
例如:狼和狗共性都是犬科,犬科就是抽象出来的概念。
抽象类:
Java中可以定义没有方法体的方法,该方法具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。
抽象方法的由来:
多个对象都具备相同的功能,但是功能具体内容有所不同,那么在抽取过程中,只抽取了功能定义,并未抽取功能主体,那么只有功能声明,没有功能主体的方法称为抽象方法。
例如:狼和狗都有吼叫的方法,可是吼叫内容是不一样的。所以抽象出来的犬科虽然有吼叫功能,但是并不明确吼叫的细节。
抽象类的特点
抽象类和抽象方法必须用abstract关键字修饰。
抽象方法只有方法声明,没有方法体,定义在抽象类中。
抽象类不可以被实例化,也就是不可以用new创建对象。
原因如下:
1. 抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。例如:犬科是一个抽象的概念,真正存在的是狼和狗。
2. 而且抽象类即使创建了对象,调用抽象方法也没有意义。
3. 抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象方法后才可以创建对象,否则该子类也是抽象类。
abstract class Demo
{
abstract void show();
}
class DemoA extends Demo
{
void show()
{
System.out.println("demoa show");
}
}
class DemoB extends Demo
{
void show()
{
System.out.println("demob show");
}
}
class AbstractDemo
{
public static void main(String[] args)
{
DemoA demoA = new DemoA();
demoA.show();
DemoB demoB = new DemoB();
demoB.show();
}
}
接口
当一个抽象类中的方法都是抽象的时候,这时可以将该抽象类用灵位一种形式定义和表示,就是接口。
接口中的成员修饰符是固定的:
成员常量:public static final
成员函数:public abstract
由此得出结论,接口中成员都是公共的权限。
接口是对外暴露的规则。
接口是程序的功能扩展。
P.S.
1、虽然抽象类中的全局变量和抽象方法的修饰符都可以不用写,但是这样阅读性很差。所以,最好写上。
2、类与类之间是继承关系,类与接口直接是实现关系。
3、接口不可以实例化,能由实现了接口并覆盖了接口中所有的抽象方法的子类实例化。否则,这个子类就是一个抽象类。
interface Demo
{
public static final int NUM = 4;
public abstract void show1();
public abstract void show2();
}
class DemoImp1 implements Demo
{
public void show1(){}
public void show2(){}
}
class InterfaceDemo
{
public static void main(String[] args)
{
DemoImp1 d = new DemoImp1();
System.out.println(d.NUM);//4
System.out.println(DemoImpl.NUM);//4
System.out.println(Demo.NUM);//4
}
}
接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
在java中不直接支持多继承,因为会出现调用的不正确性。
接口的出现避免了单继承的局限性。
interface A
{
void showA();
}
interface B
{
void showB();
}
class Test implements A,B
{
public void showA()
{
System.out.println("a");
}
public void showB()
{
System.out.println("b");
}
}
class InterfaceDemo
{
public static void main(String[] args)
{
Test t = new Test();
t.showA();
t.showB();
}
}
一个类在继承另一个类的同时,还可以实现多个接口。
抽象类和接口的异同点?
相同点:
都是不断向上抽取而来的。
不同点:
1. 抽象类需要被继承,而且只能单继承。
接口需要被实现,而且可以多实现。
2. 抽象类中可以定义抽象方法和非抽象方法,子类继承后,可以直接使用非抽象方法。
接口中只能定义抽象方法,必须由子类去实现。
3. 抽象类的继承,是is a关系,定义该体系的基本共性内容。
接口的实现是like a关系。
多态
定义:某一类事物的多种存在形态。
例:动物中猫,狗。
猫这个对象对应的类型是猫类型:猫x=new猫(); 同时猫也是动物中的一种,也可以把猫称为动物:动物y=new猫();
动物是猫和狗具体事物中抽取出来的父类型。
父类型引用指向了子类对象。
多态性简单说就是一个对象对应着不同类型。
体现:
父类或者接口的引用指向或者接收自己的子类对象。
作用:
多态的存在提高了程序的扩展性和后期可维护性。
前提:
1.需要存在继承或者实现关系。
2.需要有覆盖操作。
好处:
提高了代码的扩展性,前期定义的代码可以使用后期的内容。
弊端:
前期定义的内容不能使用(调用)后期子类的特有内容。
abstract class Animal
{
void eat();
}
class Dog extends Animal
{
void eat()
{
System.out.println("啃骨头");
}
void lookHome()
{
System.out.println("看家");
}
}
class Cat extends Animal
{
void eat()
{
System.out.println("吃鱼");
}
void catchMouse()
{
System.out.println("抓老鼠");
}
}
class DuotaiDemo
{
public static void main(String[] args)
{
Cat c = new Cat();
Dog d = new Dog();
method(c);
method(d);
}
public static void method(Animal a)
{
a.eat();
}
}
内部类
定义:
将一个类定义在另一个类的里面,里面那个类就称为内部类(内置类,嵌套类)。
访问特点:
内部类可以直接访问外部类中的成员,包括私有成员。
而外部类要访问内部类中的成员必须要建立内部类的对象。
示例1:
/*
内部类的设计:
分析事物时,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容,这时候就定义
内部类。
*/
class Outer
{
private int num = 3;
class Inner //内部类
{
void show()
{
System.out.println("show run..."+num);
}
}
public void method()
{
Inner in = new Inner();
in.show();
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();//show run...3
}
}
示例2:
class Outer
{
private int num = 3;
class Inner //内部类
{
void show()
{
System.out.println("show run..."+num);
}
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
Outer in = new Outer().new Inner();
in.show();//show run...3
}
}
内部类的位置:
内部类定义在成员位置上,可以被private、static成员修饰符修饰。被static修饰的内部类只能访问外部类中
的静态成员
示例1:
class Outer
{
private int num = 3;
static class Inner //内部类
{
void show()
{
System.out.println("show run..."+num);
}
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
//如果内部类是静态的,相当于一个外部类
Outer in = new Outer.Inner();
in.show();//show run...3
}
}
如果内部类是静态的,内部类成员也是静态的,可以不用创建内部类对象,直接调用。
示例2:
class Outer
{
private int num = 3;
static class Inner //内部类
{
static void show()
{
System.out.println("show run..."+num);
}
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
Outer.Inner.show();
}
}
如果内部类中定义了静态成员,该内部类也必须是静态的!
2、为什么内部类能直接访问外部类中的成员呢?
那是因为内部类持有了外部类的引用,外部类名.this。
class Outer
{
int num = 3;
class Inner //内部类
{
int num = 4;
void show()
{
int num = 5;
System.out.println(num);//5
Systme.out.println(this.num);//4
System.out.println(Outer.this.num);//3
}
}
void method()
{
new Inner().show();
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
new Outer().method();
}
}
3、内部类定义在局部位置上,也可以直接访问外部类中的成员。
同时可以访问所在局部中的局部变量,但必须是被final修饰的。
class Outer
{
int num = 3;
void method(final int y)
{
final int x = 9;
class Inner
{
void show()
{
System.out.println("show..."+x+","+y);//show...9,4
}
} new Inner().show();
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
new Outer().method(4);
}
}
匿名内部类
定义:
就是内部类的简化写法。
前提:
内部类可以继承或实现一个外部类或者接口。
格式:
new外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}
简单理解:
就是建立一个带内容的外部类或者接口的子类匿名对象。
什么时候使用匿名内部类呢?
通常使用方法是接口类型参数,并且该接口中的方法不超过三个,可以将匿名内部类作为参数传递。
好处:
增强阅读性。
abstract class Demo
{
abstract void show();
}
class Outer
{
int num = 3;
void method()
{
new Demo()
{
void show()
{
System.out.println("show....."+num);
}
}.show();
}
}
class InnerClassDemo
{
public static void main(String[] args)
{
new Outer().method();
}
}
对象的初始化过程
class Fu
{
int num = 9;
{
System.out.println("Fu");
}
Fu()
{
super();//Object
//显示初始化
//构造代码块初始化
show();
}
void show()
{
System.out.println("fu show "+num);//被覆盖,运行子类的
}
}
class Zi extends Fu
{
int num = 8;
{
System.out.println("Zi");
}
Zi()
{
super();
//显示初始化
//构造代码块初始化
show();
}
void show()
{
System.out.println("zi show "+num);
}
}
class Demo
{
public static void main(String[] args)
{
new Zi();// Fu zi show 0 zi zi show 8
}
}
异常
异常:是在运行时期发生的不正常情况。
在Java中用类的形式对不正常情况进行了描述和封装对象。描述不正常的情况的类,就称为异常类。
1.以前正常流程代码和问题处理代码相结合,现在将正常流程代码和问题处理代码分离,提高阅读性。
2.其实异常就是java通过面向对象的思想将问题封装成了对象,用异常类对其进行描述。
3.不同的问题用不同的类进行具体的描述。比如角标越界、空指针异常等等。
4.问题很多,意味着描述的类也很多,将其共性进行向上抽取,形成了异常体系。
自定义异常
如果让一个类成为异常类,必须要继承异常体系,因为只有成为异常体系的子类才有资格具备可抛性,才可
以被两个关键字所操作:throws、throw。
自定义类继承Exception或者其子类,通过构造函数定义异常信息。
class DemoException extends Exception
{
DemoException(String msg)
{
super(msg);
}
}
通过throw将自定义异常抛出。throws和throw的区别:
1.throws用于标识函数暴露出的异常类,并且可以抛出多个,用逗号分隔。throw用于抛出异常对象。
2.thorws用在函数上,后面跟异常类名。throw用在函数内,后面跟异常对象。
定义功能方法时,需要把出现的问题暴露出来让调用者去处理,那么就通过throws在函数上标识。
在功能方法内部出现某种情况,程序不能继续运行,需要进行跳转时,就用throw把异常对象抛出。
class ExceptionDemo
{
public static void main(String[] args) throws FuShuIndexException
{
int[] arr = new int[3];
method(arr,-30);
}
public static int method(int[] arr,int index) throws FuShuIndexException
{
if(index<0)
{
throw new FuShuIndexException("数组的角标是负数啦");
}
return arr[index];
}
}
class FuShuIndexException extends Exception
{
FuShuIndexException(){}
FuShuIndexException(String msg)
{
super(msg);
}
}
异常的分类:
1.编译时被检测异常:只要是Exception和其子类都是,除了特殊子类RuntimeException体系。 这种问题一旦出现,希望在编译时就进行检测,让这种问题有对应的处理方式。这样的问题都可以针对性的处理。
2.编译时不检测异常(运行时异常):就是Exception中的RuntimeException和其子类。
这种问题的发生,无法让功能继续,运算无法运行,更多是因为调用的原因导致的或者引发了内部状态的改变导致的。那么这种问题一般不处理,直接编译通过,在运行时,让调用者调用时的程序强制停止,让调用者对代码进行调整。所以自定义异常时,要么继承Exception,要么继承RuntimeException。
P.S.
RuntimeException是那些可能在Java虚拟机正常运行期间抛出的异常的超类。
可能在执行方法期间抛出但未被捕获的RuntimeException的任何子类都无需在throws子句中进行声明。
异常处理的捕捉形式:
可以对异常进行针对性处理的方式。
具体格式是:
try{
//需要被检测异常的代码。
}
catch(异常类变量)//该变量用于接收发生的异常对象
{
//处理异常的代码。
}
finally{
//一定会执行的代码;
}
P.S.
finally代码块只有一种情况不会被执行,就是在之前执行了System.exit(0)。
处理过程:
try中检测到异常会将异常对象传递给catch,catch捕获到异常进行处理。
finally里通常用来关闭资源。比如:数据库资源,IO资源等。
需要注意:try是一个独立的代码块,在其中定义的变量只在该变量块中有效。
如果在try以外继续使用,需要在try外建立引用,在try中对其进行初始化。IO,Socket就会遇到。
异常处理的原则:
1.函数内容如果抛出需要检测的异常,那么函数上必须要声明。
否则,必须在函数内用try/catch捕捉,否则编译失败。
2.如果调用到了声明异常的函数,要么try/catch,要么throws,否则编译失败。
3.什么时候catch,什么时候throws呢?
功能内容可以解决,用catch。
解决不了,用throws告诉调用者,由调用者解决。
4.一个功能如果抛出了多个异常,那么调用时,必须有对应多个catch进行针对性处理。
内部有几个需要检测的异常,就抛几个异常,抛出几个,就catch几个。
trycatchfinally代码块组合特点:
1.trycatchfinally
2.trycatch(多个):当没有资源需要释放时,可以不用定义finally。
3.tryfinally:异常无法直接catch处理,但是资源必须关闭。
异常的注意事项:
1.RuntimeException以及其子类如果在函数中被throw抛出,可以不用在函数上声明。
2.子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的
子类。
3.如果父类抛出多个异常,那么子类只能抛出父类异常的子集。
简单说:子类覆盖父类只能抛出父类的异常或者子类的子集。
P.S.
如果父类的方法没有抛出异常,那么子类覆盖时绝对不能抛,就只能try。
Object类
Object:所有类的根类。
Object是不断抽取而来,具备着所有对象都具备的共性内容。
Object类的toString方法默认返回的内容是“对象所属的类名+@+对象的哈希值(十六进制)”。
包 package 创建包
对类文件分类管理。
给类提供多层命名空间。
写在程序文件的第一行。
类名的全称是:包名.类名。
包也是一种封装形式。
package mypack;
class PackageDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
包与包之间的类进行访问,被访问的包中的类必须是public的,被访问的包中的类的方法也必须是public的。
四种权限
import 导入包
示例:
DemoA.java
package packa;
public class DemoA extends packb.DemoB
{
public void show()
{
method();
System.out.println("demoa show run");
}
}
DemoB.java
package packb
public class DemoB
{
protected void method()
{
System.out.println("demob show run");
}
}
PackageDemo.java
//import packa.DemoA;//导入了packa中的DemoA类
import packa.*;//导入了packa包中所有的类
class PackageDemo
{
public static void main(String[] args)
{
DemoA d = new DemoA();
d.show();
/*
输出结果
demob show run
demoa show run
*/
}
}
示例:
有两个类:DemoA、DemoAbc。
所在文件目录如下:
packa\DemoA.class
packa\abc\DemoAbc.class
导包语句如下:
importpacka.*;
importpacka.abc.*;
Jar包
Java的压缩包。
方便项目的携带。
方便于使用,只要在classpath设置jar路径即可。
数据库驱动,SSH框架等都是以jar包体现的。
Jar包的操作:
通过jar.exe工具对jar的操作。
创建jar包:
jar-cvfmypack.jarpackapackb
查看jar包
jar-tvfmypack.jar[>定向文件]
解压缩
jar-xvfmypack.jar
自定义jar包的清单文件
jar–cvfmmypack.jarmf.txtpackapackb