java之面向对象

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">1.面向对象的概念</span>

1.1理解面向对象

1.1.1面向对象是相对面向过程而言

面向对象和面向过程都是一种思想

面向过程

强调的是功能行为

面向对象

将功能封装进对象,强调具备了功能的对象

面向对象是基于面向过程的


1.2面向对象的特点

2.类与对象的关系

2.1 面向对象的三大特征:封装,继承,多态

以后开发:其实就是找对象使用,没有对象就创建一个对象

找对象,建立对象,使用对象,维护对象的关系

2.2类和对象的关系。
现实生活中的对象:张三 李四。
想要描述:提取对象中共性内容。对具体的抽象。
描述时:这些对象的共性有:姓名,年龄,性别,学习java功能。
映射到java中,描述就是class定义的类。
具体对象就是对应java在堆内存中用new建立实体。

类就是:对现实生活中事物的描述。
对象:就是这类事物,实实在在存在个体。
举例说明:

需求:描述汽车(颜色,轮胎数)。描述事物其实就是在描述事物的属性和行为。
属性对应是类中变量,行为对应的类中的函数(方法)。
其实定义类,就是在描述事物,就是在定义属性和行为。属性和行为共同成为类中的成员(成员变量和成员方法)

class Car
{
	//描述颜色
	String color = "红色";
	//描述轮胎数
	int num = 4;
	//运行行为。
	void run()
	{

		System.out.println(color+".."+num);
	}
}


class  CarDemo
{
	public static void main(String[] args) 
	{
		//生产汽车。在java中通过new操作符来完成。
		//其实就是在堆内存产生一个实体。
		//Car c = new Car();//c就是一个类类型变量。记住:类类型变量指向对象。

		//需求:将已有车的颜色改成蓝色。指挥该对象做使用。在java指挥方式是:对象.对象成员
		//c.color = "blue";
		
		//c.run();

		//Car c1 = new Car();
		//c1.run();//red 4;
		//Car c = new Car();
		//c.num = 5;
		/*
		new Car().num = 5;
		new Car().color = "blue";
		new Car().run();

		Car c = new Car();
		c.run();
		c.num = 4;
		new Car().run();
		*/
		//匿名对象使用方式一:当对对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简化。
		//如果对一个对象进行多个成员调用,必须给这个对象起个名字。

		//匿名对象使用方式二:可以将匿名对象作为实际参数进行传递。
		Car q = new Car();
		show(q);
		//show(new Car());
	}

	//需求:汽车修配厂。对汽车进行改装,将来的车够改成黑车,三个轮胎。
	public static void show(Car c)
	{
		c.num = 3;
		c.color = "black";
		c.run();
	}
}


2.3
成员变量和局部变量:

作用范围。
成员变量作用于整个类中。
局部变量变量作用于函数中,或者语句中。
在内存中的位置:
成员变量:在堆内存中,因为对象的存在,才在内存中存在。
局部变量:存在栈内存中。

2.4匿名对象:匿名对象是对象的简化形式

匿名对象两种使用情况

1.当对对象方法仅进行一次调用的时候

2.匿名对象可以作为实际参数进行传递(调用方法是有用的,调用属性没有意义)

3.封装

3.1 封装:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式

好处:使变化隔离,便于使用,提高重用性,提高安全性

3.2封装原则:

将不需要对外提供的内容隐藏起来

把属性都隐藏,提供公共方法对其访问

以person为例:

private :私有,权限修饰符:用于修饰类中的成员(成员变量,成员函数)。
私有只在本类中有效。


将age私有化以后,类以外即使建立了对象也不能直接访问。
但是人应该有年龄,就需要在Person类中提供对应访问age的方式。


注意:私有仅仅是封装的一种表现形式。




之所以对外提供访问方式,就因为可以在访问方式中加入逻辑判断等语句。
对访问的数据进行操作。提高代码健壮性。

例子程序:

public class personDemo {
	public static void main(String[] args) {
		person p = new person();
		p.setAge(-20);
		p.speak();

	}

}
class person{
	private int age;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
	void speak(){
		if(age>0&&age<150){
			System.out.println("age="+age);
		}
		else{
			System.out.println("年龄输入不正确");
		}
	}
}

4.构造函数

4.1特点:

函数名与类名相同

不定义返回值

不可以写return语句

作用:给对象进行初始化

注意:1.默认构造函数的特点。2 多个构造函数是以重载的形式存在的

对象一建立就会调用与之对应的构造函数。
构造函数的作用:可以用于给对象进行初始化。
构造函数的小细节:
当一个类中没有定义构造函数时,那么系统会默认给该类加入一个空参数的构造函数。
当在类中自定义了构造函数后,默认的构造函数就没有了。
构造函数和一般函数在写法上有不同。
在运行上也有不同。
构造函数是在对象一建立就运行。给对象初始化。
而一般方法是对象调用才执行,给是对象添加对象具备的功能。
一个对象建立,构造函数只运行一次。
而一般方法可以被该对象调用多次。
什么时候定义构造函数呢?
当分析事物时,该事物存在具备一些特性或者行为,那么将这些内容定义在构造函数中。

class PersonDemo
{
	public static void main(String[] args) 
	{
		person p=new person();
		person p1=new person("limei");
		person p2=new person("limei",15);
		p1.setname("li");
		System.out.println(p1.getname());
		p.cry();

	}

}
class person
{
	private String name;
	private int age;
	person(){
		System.out.println("name="+name+"age="+age);
		cry();
	}
	person(String n){
		name=n;
		System.out.println("name="+name+"age="+age);
		cry();
	}
	person(String n,int m){
		name=n;
		age=m;
		System.out.println("name="+name+"age="+age);
		cry();
	}
	public void setname(String n){
		name=n;
	}
	public String getname(){
		return name;
	}
	public void cry(){
		System.out.println("Cry…………");	
	}
}

4.2构造代码块

构造代码块。
作用:给对象进行初始化。
对象一建立就运行,而且优先于构造函数执行。
和构造函数的区别:
构造代码块是给所有对象进行统一初始化,
而构造函数是给对应的对象初始化。
构造代码快中定义的是不同对象共性的初始化内容。

{

共同要执行的代码

}

5.this关键字:1.代表本类对象,2构造函数之间调用

5.1this:看上去,是用于区分局部变量和成员变量同名情况。
this为什么可以解决这个问题?
this到底代表的是什么呢?
this:就代表本类的对象,到底代表哪一个呢?
this代表它所在函数所属对象的引用。
简单说:哪个对象在调用this所在的函数,this就代表哪个对象。
this的应用:当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。
但凡本类功能内部使用了了本类对象,都用this表示。

举例:
需求:给人定义一个用于比较年龄是否相同的功能。也就是是否是同龄人。

public class PersonDemo3 {
	public static void main(String[] args) {
		people p1 = new people(20);
		people p2 = new people(20);
		boolean b = p1.compare(p2);//p1调用compare那么此时的this.age相当于p1.age
		System.out.println(b);

	}

}
class people{
	private String name;
	private int age;
	people(int age){
		this.age = age;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name){ //this 表示对象的引用
		this.name = name;
	}
	public boolean compare(people p){
		return this.age==p.age;
	}
}

5.2this语句 :用于构造函数之间进行互相调用。
this语句只能定义在构造函数的第一行。因为初始化要先执行。

class PersonDemo4 
{
	public static void main(String[] args) 
	{
		Person1 p = new Person1("lisi",15);
		//Person1 p1 = new Person1("lisi12",15);
	}
}
class Person1
{
	private String name;
	private int age;
	Person1(){
	}
	Person1(int age){
		this();//相当于调用person1()
		this.age = age;
	}
	Person1(String name){
		this.name = name;·
	}
	Person1(String name,int age){
		//this.name= name;
		this(name);//相当于p(name);
		this.age = age;
	}
}

6.static关键字

6.1 static 关键字:用于修饰成员(成员变量和成员函数)

     被static修饰后的成员具备以下的特点:

随着类的加载而加载

优先于对象存在

被所有对象所共享

可以直接被类名调用

 使用注意:静态方法只能访问静态成员

静态方法中不可以写this,super关键字

主函数是静态的

6.2

静态:static。
用法:是一个修饰符,用于修饰成员(成员变量,成员函数).
当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,
还可以直接被类名调用。类名.静态成员。




static特点:
1,随着类的加载而加载。
   也就说:静态会随着类的消失而消失。说明它的生命周期最长。


2,优先于的对象存在
明确一点:静态是先存在。对象是后存在的。


3,被所有对象所共享
4,可以直接被类名所调用。


实例变量和类变量的区别:
1,存放位置。
类变量随着类的加载而存在于方法区中
实例变量随着对象的建立而存在于堆内存中。
2,生命周期:
类变量生命周期最长,随着类的消失而消失。
实例变量生命周期随着对象的消失而消失。






静态使用注意事项:
1,静态方法只能访问静态成员。
非静态方法既可以访问静态也可以访问非静态。

2,静态方法中不可以定义this,super关键字。
因为静态优先于对象存在。所以静态方法中不可以出现this。
3,主函数是静态的。

静态有利有弊
利处:对对象的共享数据进行单独空间的存储,节省空间。没有必要每一个对象中都存储一份。
可以直接被类名调用。
弊端:生命周期过长。
  访问出现局限性。(静态虽好,只能访问静态。)


6.3 java主函数:

public static void main(String[] args) 

主函数:是一个特殊的函数。作为程序的入口,可以被jvm调用。

主函数的定义:
public:代表着该函数访问权限是最大的。
static:代表主函数随着类的加载就已经存在了。
void:主函数没有具体的返回值。
main:不是关键字,但是是一个特殊的单词,可以被jvm识别。
(String[] arr):函数的参数,参数类型是一个数组,该数组中的元素是字符串。字符串类型的数组。

主函数是固定格式的:jvm识别。

jvm在调用主函数时,传入的是new String[0];

6.4什么时候使用静态:

什么使用静态?
要从两方面下手:
因为静态修饰的内容有成员变量和函数。
什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,该数据被静态所修饰。
对象中的特有数据要定义成非静态存在于堆内存中。
什么时候定义静态函数呢?
当功能内部没有访问到非静态数据(对象的特有数据),
那么该功能可以定义成静态的。


6.5静态应用工具类:

静态的应用。制作doc文档


每一个应用程序中都有共性的功能,
可以将这些功能进行抽取,独立封装。
以便复用。
虽然可以通过建立ArrayTool的对象使用这些工具方法,对数组进行操作。
发现了问题:
1,对象是用于封装数据的,可是ArrayTool对象并未封装特有数据。
2,操作数组的每一个方法都没有用到ArrayTool对象中的特有数据。

这时就考虑,让程序更严谨,是不需要对象的。
可以将ArrayTool中的方法都定义成static的。直接通过类名调用即可。

将方法都静态后,可以方便于使用,但是该类还是可以被其他程序建立对象的。
为了更为严谨,强制让该类不能建立对象。
可以通过将构造函数私有化完成。
接下来,将ArrayTool.class文件发送给其他人,其他人只要将该文件设置到classpath路径下,就可以使用该工具类。
但是,很遗憾,该类中到底定义了多少个方法,对方去不清楚。因为该类并没有使用说明书。
开始制作程序的说明书。java的说明书通过文档注释来完成。

/**
这是一个可以对数组进行操作的工具类,该类中提供了,获取最值,排序等功能。
@author 张三
@version V1.1

*/

//javadoc -d myhelp -author -version ArrayTool.java(doc命令行中)类必须是public

在MyEclipe中点击project--->Generate  javadoc 选择要生成javadoc的类即可

程序:

/**
这是一个操作数组的类
@author 王佳宁
@version v1.1
*/

class ArrayToolDemo {
	public static void main(String[] args) {
		int arr[]=new int[]{3,4,6,2,8,67,5};
		ArrayTool.quickSort(arr);
		
		System.out.println("MAX="+ArrayTool.getMax(arr));
		ArrayTool.print(arr);

	}

}
 public class ArrayTool{
	private ArrayTool(){}
	/**
	获取数组的最大值
	@param arr 接受一个int类型的数组
	@return 返回数组中的最大值
	*/
	public static int getMax(int arr[]){
		int max = 0;
		for(int i = 0;i<arr.length;i++){
			if(max<arr[i])
				max = arr[i];
		}
		return max;
	}
	/**获取数组的最小值
	@param arr 接受一个int类型的数组
	@return 返回数组中的最小值*/
	
	public static int getmin(int arr[]){
		int min=0;
		for(int i=0;i<arr.length;i++){
			if(min>arr[i]){
				min=arr[i];
			}
		}
		return min;
	}
	/**
	交换位置
	@param arr 接受一个int类型的数组
    @param a 要换的位置1
	@param b 要换的位置2

	*/
	public static void swap(int arr[],int i,int j){
		int temp = arr[i];
		arr[i] = arr[j];
		arr[j]=temp;
	}
	/**
	快速排序法
	@param arr 接受int类型的数组
	*/
	public static void quickSort(int arr[]){
		for(int i = 0;i<arr.length;i++){
			for(int j = i+1;j<arr.length;j++){
				if(arr[i]>arr[j]){
					swap(arr,i,j);
				}
			}
		}
	}
	/**
	冒泡排序法
	@param arr 接受int类型的数组
	*/
	public static void bubbleSort(int arr[]){
		for(int i = 0;i<arr.length;i++){
			for(int j = 0 ;j<arr.length-i-1;j++){
				
				if(arr[j]>arr[j+1])
					swap(arr,j,j+1);
			}
		}
	}
	
	/**
	数组的打印
	@param arr 接受int类型的数组
	*/
	public static void print(int arr[]){
		System.out.print("[");
		for(int i =0;i<arr.length;i++){
			if(i!=arr.length-1)
				System.out.print(arr[i]+",");
			else
				System.out.println(arr[i]+"]");
			
		}
	}
}

6.6静态代码块
静态代码块。
格式:
static
{
静态代码块中的执行语句。
}

特点:随着类的加载而执行,只执行一次,并优先于主函数。
用于给类进行初始化的。

程序举例:

public class StaticCodeDemo {

	static
	{
		System.out.println("b");
	}
	public static void main(String[] args) 
	{
		new StaticCode(4);//a c d 


	}
	static
	{
		System.out.println("c");
	}
}
//结果是bcac9d
class StaticCode
{
	int num = 9;
	StaticCode()
	{
		System.out.println("b");
	}

	static
	{
		System.out.println("a");
	}
	{
		System.out.println("c"+this.num);
	}

	StaticCode(int x)
	{
		System.out.println("d");
	}
	
}
6.7对象的初始化过程:


class Person
{
	private Person(){}
	private String name = "hah";
	private int age;
	private static  String country = "cn";
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	
	{
		System.out.println(name+".."+age);
	}
	public void setName(String name)
	{
		this.name = name;
	}

	public void speak()
	{
		System.out.println(this.name+"..."+this.age);
	}

	public static void  showCountry()
	{
		System.out.println("country="+Person.country);
		Person.method();
	}
	public static void method()
	{
		System.out.println("method run");
	}

}

class  PersonDemo
{
	public static void main(String[] args) 
	{
		Person p = new Person("zhangsan",20);
		p.setName("lisi");
		new Person();
	}
}

Person p = new Person("zhangsan",20);


该句话都做了什么事情?
1,因为new用到了Person.class.所以会先找到Person.class文件并加载到内存中。
2,执行该类中的static代码块,如果有的话,给Person.class类进行初始化。
3,在堆内存中开辟空间,分配内存地址。
4,在堆内存中建立对象的特有属性。并进行默认初始化。
5,对属性进行显示初始化。
6,对对象进行构造代码块初始化。
7,对对象进行对应的构造函数初始化。
8,将内存地址付给栈内存中的p变量。

对象初始化内存图:



对象调用成员过程图:

非静态省略this.

静态省略类名.






7.单例设计模式

设计模式:解决某一类问题最行之有效的方法。
java中23种设计模式:
单例设计模式:解决一个类在内存只存在一个对象。
想要保证对象唯一。
1,为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象
2,还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。
3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。
这三部怎么用代码体现呢?
1,将构造函数私有化。
2,在类中创建一个本类对象。
3,提供一个方法可以获取到该对象。

对于事物该怎么描述,还怎么描述。
当需要将该事物的对象保证在内存中唯一时,就将以上的三步加上即可。

举例说明:

public class SingleDemo {

	public static void main(String[] args) {
		 Single s1 = Single.getS();
		 Single s2 = Single.getS();
		 s1.setName("lisi");
		 System.out.println(s2.getName());//s1和s2是同一个对象
		 

	}

}
class Single{
	private String name;
	private Single(){}
	private static Single s = new Single();
	public static Single getS(){
		return s;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}

两种单例模式:懒汉式and饿汉式

方法一饿汉式

Single一进入内存就创建好类:

class Single1{
	private Single1(){}
	private static Single1 s = new Single1();
	public static Single1 getInstance(){
		return s;
	}
}
方法二:懒汉式

对象是方法被调用时候,才初始化,也叫对象的延时加载。叫做懒汉式

Single类进内存对象还没有存在,只有调用了getInstance方法时候,才建立 对象

class Single2{
	private Single2(){}
	private static Single2 s =null;
	public static Single2 getInstance(){
		if(s==null){
			s = new Single2();
		}
		return s;
	}
}
线程同步在单例模式中的应用:

在对外提供的方法上加上同步函数会降低效率,因此最终的解决方法是加入同步代码块

比如:

class Single2{
	private Single2(){}
	private static Single2 s =null;
	public static /*synchronized*/ Single2 getInstance(){
		if(s==null){
			synchronized(Single.class){
				if(s==null){
					s = new Single2();
				}
			}
		}
		return s;
	}
}
记住原则:定义单例,建议使用饿汉式

二:继承:

1.概述:

将学生和工人的共性描述提取出来,单独进行描述,
只要让学生和工人与单独描述的这个类有关系,就可以了。
继承:
1,提高了代码的复用性。
2,让类与类之间产生了关系。有了这个关系,才有了多态的特性。
注意:千万不要为了获取其他类的功能,简化代码而继承。
必须是类与类之间有所属关系才可以继承。所属关系 is a。
class C
{
void demo1(){}
}
class A extends C
{
//void demo1(){}
void demo2(){}
}
class B extends C
{
//void demo1(){}
void demo3(){}
}

Java语言中:java只支持单继承,不支持多继承。
因为多继承容易带来安全隐患:当多个父类中定义了相同功能,
当功能内容不同时,子类对象不确定要运行哪一个。
但是java保留这种机制。并用另一种体现形式来完成表示。多实现。
java支持多层继承。也就是一个继承体系
如何使用一个继承体系中的功能呢?
想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。
通过了解共性功能,就可以知道该体系的基本功能。
那么这个体系已经可以基本使用了。
那么在具体调用时,要创建最子类的对象,为什么呢?
一是因为有可能父类不能创建对象,
二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。
简单一句话:查阅父类功能,创建子类对象使用功能。
聚集:has a
聚集分为聚合和组合

聚合:如人组成班级,一个球队由球员组成的。
组合是谁是是的一部分,例如,手是身体的一部分。
2.子父类中变量的特点:

子父类出现后,类成员的特点:
类中成员:
1,变量。
2,函数。
3,构造函数。
1,变量
如果子类中出现非私有的同名成员变量时,
子类要访问本类中的变量,用this
子类要访问父类中的同名变量,用super。
super的使用和this的使用几乎一致。
this代表的是本类对象的引用。
super代表的是父类对象的引用。

public class ExtendsDemo2 {
	public static void main(String[] args) {
		Zi z = new Zi();
		z.show();//5
		z.showFu();//4
		System.out.println(z.num);//5

	}

}
class Fu{
	 int num = 4;

	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
}
class Zi extends Fu{
	 int num = 5;
	void show(){
		System.out.println(this.num);
	}
	void showFu(){
		System.out.println(super.num);
	}
}

2,子父类中的函数。
当子类出现和父类一模一样的函数时,
当子类对象调用该函数,会运行子类函数的内容。
如同父类的函数被覆盖一样。
这种情况是函数的另一个特性:重写(覆盖)
当子类继承父类,沿袭了父类的功能,到子类中,
但是子类虽具备该功能,但是功能的内容却和父类不一致,
这时,没有必要定义新功能,而是使用覆盖特殊,保留父类的功能定义,并重写功能内容。
覆盖:
1,子类覆盖父类,必须保证子类权限大于等于父类权限,才可以覆盖,否则编译失败。
2,静态只能覆盖静态。
记住大家:
重载:只看同名函数的参数列表。
重写:子父类方法要一模一样。

class Fu
{
	void show()
	{
		System.out.println("fu show");
	}
	void speak()
	{
		System.out.println("vb");
	}
}

class Zi extends Fu
{
	void speak()
	{
		System.out.println("java");
	}
	void show()
	{
		System.out.println("zi show");
	}
}


class ExtendsDemo3 
{
	public static void main(String[] args) 
	{
		Zi z = new Zi();
		z.speak();

	}
}
class Tel
{
	void show()
	{
		System.out.println("number");
	}
	
}

class NewTel extends Tel
{
	void show()
	{
		//System.out.println("number");
		super.show();
		System.out.println("name");
		System.out.println("pic");
	}
}
3,子父类中的构造函数。
在对子类对象进行初始化时,父类的构造函数也会运行,
那是因为子类的构造函数默认第一行有一条隐式的语句 super();
super():会访问父类中空参数的构造函数。而且子类中所有的构造函数默认第一行都是super();
为什么子类一定要访问父类中的构造函数。
因为父类中的数据子类可以直接获取。所以子类对象在建立时,需要先查看父类是如何对这些数据进行初始化的。
所以子类在对象初始化时,要先访问一下父类中的构造函数。
如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。
注意:super语句一定定义在子类构造函数的第一行。
子类的实例化过程。
结论:
子类的所有的构造函数,默认都会访问父类中空参数的构造函数。
因为子类每一个构造函数内的第一行都有一句隐式super();
当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。
当然:子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。
子类中至少会有一个构造函数会访问父类中的构造函数。

演示:

class fu //extends Object
{
	int num ;
	fu()
	{
		//super();
		num= 60;
		System.out.println("fu run");
	}
	fu(int  x)
	{
		System.out.println("fu ...."+x);
	}
	
}

class zi extends fu
{
	zi()
	{
		
		super();  
		//super(4);
		System.out.println("zi run");
	}
	zi(int x)
	{
		this();
		//super();
		//super(3);
		System.out.println("zi..."+x);
	}
}

class  ExtendsDemo4
{
	public static void main(String[] args) 
	{
		zi z = new zi(0);
		System.out.println(z.num);
	}
}
4.final : 最终。作为一个修饰符,
1,可以修饰类,函数,变量。
2,被final修饰的类不可以被继承。为了避免被继承,被子类复写功能。
3,被final修饰的方法不可以被复写。
4,被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,有可以修饰局部变量。
当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。
而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成。
单词间通过_连接。
5,内部类定义在类中的局部位置上是,只能访问该局部被final修饰的局部变量。
5抽象:看不懂。

.当多个类中出现相同功能,但是功能主体不同,
这是可以进行向上抽取。这时,只抽取功能定义,而不抽取功能主体。
抽象类的特点:
1,抽象方法一定在抽象类中。
2,抽象方法和抽象类都必须被abstract关键字修饰。
3,抽象类不可以用new创建对象。因为调用抽象方法没意义。
4,抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。
如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。
抽象类和一般类没有太大的不同。
该如何描述事物,就如何描述事物,只不过,该事物出现了一些看不懂的东西。
这些不确定的部分,也是该事物的功能,需要明确出现。但是无法定义主体。
通过抽象方法来表示。
抽象类比一般类多个了抽象函数。就是在类中可以定义抽象方法。
抽象类不可以实例化。
特殊:抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
abstract 关键字,和哪些关键字不能共存。
final:被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
private: 抽象类中的私有的抽象方法,不被子类所知,就无法被复写。
而抽象方法出现的就是需要被复写。
static:如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。
可是抽象方法运行没意义。
抽象类中是否有构造函数?
有,抽象类是一个父类,要给子类提供实例的初始化。

class  testabstract
{
	public static void main(String[] args) 
	{
		new boss("li","12545",154,23).work();
		new pro("lie","154654",48).work();
	}
}

abstract class Employee
{
	private String name;
	private String id;
	private double pay;
	Employee(String name,String id,double pay){
		this.name=name;
		this.id=id;
		this.pay=pay;
	}
	public abstract void work();
}
class boss extends Employee
{
	private int bonus;
	boss(String name,String id,double pay,int bonus){
		super(name,id,pay);
		this.bonus=bonus;
	}
	public void work(){
		System.out.println("boss work");
	}
}
class pro extends Employee
{
	pro(String name,String id,double pay){
		super(name,id,pay);
	}
	public  void work(){
		System.out.println("pro work");
	}
}
结果:
boss work
pro work
6.模板设计模式:

在定义功能的时候,功能一部分是确定的,但是有一部分是不确定的,而确定的部分在使用不确定的部分,

那么这时候就将不确定的部分暴露出去,由该子类进行完成。


需求:获取一段程序运行的时间,

原理:获取程序开始和结束的时间并相减即可,获取时间:System.currentTimeMillis();

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		sub s = new sub();
		s.time();

	}

}
abstract class getTime{
	public final void time(){
		long start = System.currentTimeMillis();
		run();
		long end = System.currentTimeMillis();
		System.out.println("运行时间:"+(end-start));
	}
	public abstract void run();
}

class sub extends getTime{
	public void run(){
		for(int i = 0;i<5;i++){
			System.out.println(i);
		
		}
	}
}
7.接口:

格式 interface{}

接口中的成员修饰符是固定的:

成员常量:public static final

成员函数:public abstract

接口:初期理解,可以认为是一个特殊的抽象类
当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。
class用于定义类
interface 用于定义接口。
接口定义时,格式特点:
1,接口中常见定义:常量,抽象方法。
2,接口中的成员都有固定修饰符。
常量:public static final
方法:public abstract 
记住:接口中的成员都是public的。
接口:是不可以创建对象的,因为有抽象方法。
需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。
否则子类是一个抽象类。
接口可以被类多实现,也是对多继承不支持的转换形式。java支持多实现。
接口的特点:接口是对外暴露的规则,接口是程序的功能扩展,接口可以用来多实现

类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口,接口与接口之间可以有继承关系

8.多态:

多态:可以理解为事物存在的多种体现形态。
人:男人,女人
动物:猫,狗。
猫 x = new 猫();
动物 x = new 猫();
1,多态的体现
父类的引用指向了自己的子类对象。
父类的引用也可以接收自己的子类对象。
2,多态的前提
必须是类与类之间有关系。要么继承,要么实现。
通常还有一个前提:存在覆盖。
3,多态的好处
多态的出现大大的提高程序的扩展性。
4,多态的弊端:
提高了扩展性,但是只能使用父类的引用访问父类中的成员。
5,多态的应用

6,多态的出现代码中的特点(多态使用的注意事项)3
第二个问题:如何使用子类特有方法。

举例:

public class DuoTaiDemo {
	public static void main(String[] args){
		Animal x = new Cat();
		x.eat();
	}
}
abstract class Animal{
	public abstract void eat();
	
	
}
class Cat extends Animal{
	public void eat(){
		System.out.println("猫猫爱吃鱼");
	}
	public void catchMouse(){
		System.out.println("猫猫在抓鱼");
	}
}
class Pig extends Animal{
	public void eat(){
		System.out.println("猪猪在哼哼");
	}
	public void gongdi(){
		System.out.println("猪猪在拱地");
	}
}

8.2多态转型问题:

package com.wjn.face;

public class DuoTaiDemo {
	public static void main(String[] args){
		//Animal a = new Cat();//类型提升。 向上转型。
		//a.eat();

		//如果想要调用猫的特有方法时,如何操作?
		//强制将父类的引用。转成子类类型。向下转型。
		//Pig c = (Pig)a;
		//c.eat();//这样就会出错!!类型转换异常
		//c.catchMouse();
		//千万不要出现这样的操作,就是将父类对象转成子类类型。
		//我们能转换的是父类应用指向了自己的子类对象时,该应用可以被提升,也可以被强制转换。
		//多态自始至终都是子类对象在做着变化。
				//Animal a = new Animal();
				//Cat c = (Cat)a;
		Animal x = new Cat();
		x.eat();
		function(x);
		Animal y = new Pig();
		function(y);
	}
	public static void function(Animal a){
		/*
		instanceof : 用于判断对象的类型。 对象 intanceof 类型(类类型 接口类型)  
		*/
		if(a instanceof Pig){
			Pig c = (Pig)a;
			c.eat();
		}
		else {
			System.out.println("类型不匹配");
		}
	}
}
abstract class Animal{
	public abstract void eat();
	
	
}
class Cat extends Animal{
	public void eat(){
		System.out.println("猫猫爱吃鱼");
	}
	public void catchMouse(){
		System.out.println("猫猫在抓鱼");
	}
}
class Pig extends Animal{
	public void eat(){
		System.out.println("猪猪在哼哼");
	}
	public void gongdi(){
		System.out.println("猪猪在拱地");
	}
}

多态成员的特点:

在多态中成员函数的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。如果有,编译通过,如果没有编译失败。
在运行时期:参阅对象所属的类中是否有调用的方法。
简单总结就是:成员函数在多态调用时,编译看左边,运行看右边。
在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。
在多态中,静态成员函数的特点:
无论编译和运行,都参考做左边。

public class ExtendsDemo5 {
	public static void main(String[] args) {
		FuLei f = new zilei();
		System.out.println(f.x);//成员变量无论编译还是运行都看左边
		System.out.println(f.num);//静态看左边所以输出父类的成员变量值
		f.method3();//静态的时候只看左边,也就是父类
		f.method1();//非静态的时候是编译看左边,运行看右边

	}

}
class FuLei{
	int x =3;
	static int num=2;
	void method1(){
		System.out.println("fulei_____1");
	}
	void method2(){
		System.out.println("fulei_____2");
	}
	static void method3(){
		System.out.println("static fulei______3");
	}
}

class zilei extends FuLei{
	static int num = 5;
	int x = 4;
	void method1(){
		System.out.println("zilei____1");
	}
	void method4(){
		System.out.println("zilei___4");
	}
	static void method3(){
		System.out.println("zilei___3");
	}
}

举例:
需求:电脑运行实例,电脑运行基于主板
public class maincardTest {
	public static void main(String[] args) {
		maincard m = new maincard();
		m.run();
		m.use(new netcard());
		m.use(new yinyue());

	}

}
interface pci{
	public void open();
	public void close();
}
class netcard implements pci{

	public void close() {
		System.out.println("netcard is close");
		
	}

	public void open() {
	System.out.println("netcard is open");
		
	}
	
}
class yinyue implements pci
{
	
	public void open(){
		System.out.println("yinyue run");
	}
	public void close(){
		System.out.println("yinyue close");
	}
}
 class maincard{
	public void run(){
		System.out.println("main run");
	}
	public void use(pci p){
		p.open();
		p.close();
	}
}

9.Object 中的equals

Object:是所有对象的直接后者间接父类,传说中的上帝。
该类中定义的肯定是所有对象都具备的功能。
Object类中已经提供了对对象是否相同的比较方法。
如果自定义类中也有比较相同的功能,没有必要重新定义。
只要沿袭父类中的功能,建立自己特有比较内容即可。这就是覆盖。

public class ObjectDemo {
	public static void main(String[] args) {
		Demo d1 = new Demo(4);
		Demo d2 = new Demo(4);
		System.out.println(d1.equals(d2));
		ss s = new ss();
		System.out.println(d1.equals(s));
		System.out.println(d1.toString());
		System.out.println(d1);//输出语句打印对象时,会自动调用对象的toString方法。打印对象的字符串表现形式。
		//不复写的时候就是getClass.getName+'@'+Integer.toHexString(hashCode())
		System.out.println(d1.getClass().getName()+"@@"+Integer.toHexString(d1.hashCode()));
	}

}
class ss{
	
}
class Demo{//extends Object
	private int num ;
	Demo(int num){
		this.num = num;
	}
	public String getName() {
		// TODO Auto-generated method stub
		return null;
	}
	public boolean equals(Object obj){
		if(!(obj instanceof Demo)){
			return false;
		}
		Demo d = (Demo)obj;
		return this.num==d.num;
	}
	/*public String toString(){
		return "Demo"+num;
	}*/
}

10 内部类:

10.1内部类的访问规则
1,内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
2,外部类要访问内部类,必须建立内部类对象。

public class InnerClassDemo {

	public static void main(String[] args) {
		Outer out = new Outer();
		
		out.method();
		//直接访问
		/*Outer.Inner in = new Outer().new Inner();//如果是私有的就不能直接访问
		in.function();*/

	}

}
class Outer{
	private int num = 3;
	private class Inner{
		int num = 4;
		void function(){
			int num = 5;
			System.out.println("inner"+Outer.this.num+"..."+this.num+"..."+num);//outer.this.x打印的是3,this.x打印的是4,x打印的是5
		}
	}
	void method(){
		Inner i = new Inner();
		i.function();
	}
}
访问格式:
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的。

class  Inner
{
	public static void main(String[] args) 
	{
		outer o = new outer();
		o.method();
		System.out.println("_______________");
		//直接访问内部类
		outer.inner ou = new outer().new inner();
		ou.function();
	}
}

class outer
{
	private int x = 3;
	 class inner//内部类可以私有,(私有的话就不能访问了)
	{
		int x=4;
		public void function(){
			int x=6;
			System.out.println("inner"+outer.this.x);//outer.this.x打印的是3,this.x打印的是4,x打印的是6
		}
	}
	void method(){
		inner i = new inner();
		i.function();
	}
}


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

因为内部事务在使用外部事物的内容。

一般用于程序设计,一般内部类不直接被访问,通过提供方法来访问。

class Body
{
private class XinZang
{


}


public void show()
{
new XinZang().
}

}

class Outer
{
	private static  int x = 3;

	
	static class Inner//静态内部类
	{
		static void function()
		{
			System.out.println("innner :"+x);
		}
	}

	static class Inner2
	{
		void show()
		{
			System.out.println("inner2 show");
		}
	}

	public static void method()
	{
		//Inner.function();
		new Inner2().show();
	}

}


class  InnerClassDemo2
{
	public static void main(String[] args) 
	{
		Outer.method();
		//Outer.Inner.function();
		//new Outer.Inner().function();
		//直接访问内部类中的成员。
//		Outer.Inner in = new Outer().new Inner();
//		in.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);
			}
		}
	
		new Inner().function();
		
	}
}


class  InnerClassDemo3
{
	public static void main(String[] args) 
	{
		Outer out = new Outer();
		out.method(7);
		out.method(8);
	}

}
匿名内部类:
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
3,匿名内部类的格式:  new 父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。 可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个。
abstract class AbsDemo
{
	abstract void show();
	
}


class Outer
{
	int x = 3;

	/*
	class Inner extends AbsDemo
	{
		int num = 90;
		void show()
		{
			System.out.println("show :"+num);
		}
		void abc()
		{
			System.out.println("hehe");
		}
	}
	*/

	public void function()
	{
		//AbsDemo a = new Inner();
//		Inner in = new Inner();
//		in.show();
//		in.abc();
	

		AbsDemo d = new AbsDemo()
		{
			int num = 9;
			void show()
			{
				System.out.println("num==="+num);
			}
			void abc()
			{
				System.out.println("haha");
			}
		};

		d.show();
		//d.abc();//编译失败;

		



	}
}



class InnerClassDemo4 
{
	public static void main(String[] args) 
	{
		new Outer().function();
	}
}

练习:补全代码:Test.function().method

interface Inter
{
	void method();
}

class Test 
{
	//补足代码。通过匿名内部类。
	/*
	static class Inner implements Inter
	{
		public void method()
		{
			System.out.println("method run");
		}
	}
	*/

	static Inter function()
	{
		return new Inter()
		{
			public void method()
			{
				System.out.println("method run");
			}
		};
	}

}



class InnerClassTest 
{
	public static void main(String[] args) 
	{

		//Test.function():Test类中有一个静态的方法function。
		//.method():function这个方法运算后的结果是一个对象。而且是一个Inter类型的对象。
		//因为只有是Inter类型的对象,才可以调用method方法。


		Test.function().method();
		

//		Inter in = Test.function();
//		in.method();


		show(new Inter()
		{
			public void method()
			{
				System.out.println("method show run");
			}
		});

	}

	public static void show(Inter in)
	{
		in.method();
	}
}

class InnerTest
{

	public static void main(String[] args)
	{
		new Object()
		{
			public void function()
			{
				
			}
			
		}.function();


	}
}
二异常:

异常:就是程序在运行时出现不正常情况。
异常由来:问题也是现实生活中一个具体的事物,也可以通过java的类的形式进行描述。并封装成对象。
其实就是java对不正常情况进行描述后的对象体现。


对于问题的划分:两种:一种是严重的问题,一种非严重的问题。


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


对与非严重的,java通过Exception类进行描述。
对于Exception可以使用针对性的处理方式进行处理。


无论Error或者Exception都具有一些共性内容。
比如:不正常情况的信息,引发原因等。


Throwable
|--Error
|--Exception








2,异常的处理


java 提供了特有的语句进行处理。
try
{
需要被检测的代码;
}
catch(异常类 变量)
{
处理异常的代码;(处理方式)
}
finally
{
一定会执行的语句;
}
3,对捕获到的异常对象进行常见方法操作。
String getMessage():获取异常信息。

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");

	}
}

在函数上声明异常。
便于提高安全性,让调用出进行处理。不处理编译失败。

class exception2
{
	public static void main(String[] args) throws Exception
	{
		demo d = new demo();
			int x = d.div(4,0);
			System.out.println(x);
		System.out.println("over");
	}
}

class demo
{
	public int div(int a,int b)throws Exception//在功能上通过throws 的关键字声明了该功能可能会出现问题。
    {
		return a/b;
	}
}
对多异常的处理。

1,声明异常时,建议声明更为具体的异常。这样处理的可以更具体。
2,对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。
如果多个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(Exception e)
		{
			System.out.println("hahah:"+e.toString());
		}
		catch (ArithmeticException e)
		{
			System.out.println(e.toString());
			System.out.println("被零除了!!");

		}
		catch (ArrayIndexOutOfBoundsException e)
		{
			System.out.println(e.toString());
			System.out.println("角标越界啦!!");
		}
		
		/**/
		

		System.out.println("over");

	}
}
自定义异常:

因为项目中会出现特有的问题,
而这些问题并未被java所描述并封装对象。
所以对于这些特有的问题可以按照java的对问题封装的思想。
将特有的问题。进行自定义的异常封装。

自定义异常。

需求:在本程序中,对于除数是-1,也视为是错误的是无法进行运算的。
那么就需要对这个问题进行自定义的描述。

当在函数内部出现了throw抛出异常对象,那么就必须要给对应的处理动作。
要么在内部try catch处理。
要么在函数上声明让调用者处理。

一般情况在,函数内出现异常,函数上需要声明。


发现打印的结果中只有异常的名称,却没有异常的信息。
因为自定义的异常并未定义信息。

如何定义异常信息呢?
因为父类中已经把异常信息的操作都完成了。
所以子类只要在构造时,将异常信息传递给父类通过super语句。
那么就可以直接通过getMessage方法获取自定义的异常信息。
自定义异常:
必须是自定义类继承Exception。
继承Exception原因:
异常体系有一个特点:因为异常类和异常对象都被抛出。
他们都具备可抛性。这个可抛性是Throwable这个体系中独有特点。
只有这个体系中的类和对象才可以被throws和throw操作。
throws和throw的区别
throws使用在函数上。
throw使用在函数内。
throws后面跟的异常类。可以跟多个。用逗号隔开。
throw后跟的是异常对象。

package Exception;

public class ExceptionDemo1 {
	public static void main(String[] args) {
		DemoE d = new DemoE();
		try
		{
			int x = d.div(4,-9);
			System.out.println("x="+x);		
		}
		catch (FuShuException e)
		{
			System.out.println(e.toString());
			//System.out.println("除数出现负数了");
			System.out.println("错误的负数是:"+e.getValue());
		}
		
		

		System.out.println("over");


	}

}
class FuShuException extends Exception{
	private int value;
	FuShuException(){
		super();
	}
	FuShuException(String message,int value){
		super(message);
		this.value = value;
	}
	public int getValue(){
		return value;
	}
}
class DemoE{
	public int div(int a,int b)throws FuShuException{
		if(b<0){
			throw new FuShuException("除数出现了负数",b);
		}
		return a/b;
	}
}

/*
class Throwable
{
	private String message;
	Throwable(String message)
	{
		this.message = message;
	}

	public String getMessage()
	{
		return message;
	}
}

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


class Person
{
	String name;
	Person(String name)
	{
		this.name = name;
	}
	public String getName()
	{
		return name;
		}
}

class Student extends Person
{
	Student (String name)
	{
		super(name);
	}
}

new Sttdent("lisi").getName();

*/
Exceptoin中有一个特殊的子类异常RuntimeException 运行时异常。
如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。
如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过;
之所以不用在函数声明,是因为不需要让调用者处理。
当该异常发生,希望程序停止。因为在运行时,出现了无法继续运算的情况,希望停止程序后,
对代码进行修正。
自定义异常时:如果该异常的发生,无法在继续进行运算,
就让自定义异常继承RuntimeException。
对于异常分两种:
1,编译时被检测的异常。
2,编译时不被检测的异常(运行时异常。RuntimeException以及其子类)

package Exception;

public class ExceptionDemo2 {
	public static void main(String[] args) {
		DemoException1 d = new DemoException1();
		int x = d.div(4,-1);
		System.out.println(x);

	}

}
class FushuException extends RuntimeException{
	FushuException(String mess){
		super(mess);
	}
}
class DemoException1{
	 int div(int a,int b){
		if(b<0){
			throw new FushuException("出现负数");
		}
		if(b==0){
			throw new ArithmeticException("除数为0了");
		}
		return a/b;
	}
}
异常练习:计算机蓝屏和冒烟问题:

public class ExceptionDemo3 {
	public static void main(String[] args) {
		teacher t = new teacher("miss li");
		try {
			t.prelect();
		} catch (NoPlan e) {
			System.out.println(e.toString());
			System.out.println("换老师,或者换电脑");
		}

	}

}
class LanPing extends Exception{
	LanPing(String mess){
		super(mess);
	}
}
class MaoYan extends Exception{
	MaoYan(String mess){
		super(mess);
	}
}
class NoPlan extends Exception
{
	 NoPlan(String msg)
	{
		super(msg);
	}
}
class computer{
	private int state = 3;
	public void run() throws LanPing, MaoYan{
		if(state==2)
			throw new LanPing("蓝屏了");
		if(state==3)
			throw new MaoYan("冒烟啦");

		System.out.println("run");
	}
	public void reset(){
		state = 1;
		System.out.println("reset");
	}
}
class teacher{
	private String name;
	private computer cmp;
	teacher(String name){
		this.name = name;
		cmp = new computer();
	}
	public void prelect() throws NoPlan{
		try {
			cmp.run();
		} catch (LanPing e) {
			cmp.reset();
			e.printStackTrace();
		} catch (MaoYan e) {
			test();
			throw new NoPlan("课程无法继续"+e.getMessage());
		}
	}
	public void test(){
		System.out.println("练习");
	}
}
finally:

finally代码块:定义一定执行的代码。
通常用于关闭资源。
class FuShuException extends Exception
{
	FuShuException(String msg)
	{
		super(msg);
	}
}

class Demo
{
	int div(int a,int b)throws FuShuException
	{
		if(b<0)
			throw new FuShuException("除数为负数");
		return a/b;
	}
}

class  ExceptionDemo5
{
	public static void main(String[] args) 
	{
		Demo d = new Demo();

		try
		{
			int x = d.div(4,-1);
			System.out.println("x="+x);

		}
		catch (FuShuException e)
		{
			System.out.println(e.toString());
			return;
			//System.exit(0);//系统,退出。jvm结束。
		}
		finally
		{
			System.out.println("finally");//finally中存放的是一定会被执行的代码。
		}


		System.out.println("over");
	}
}

异常处理的几种格式:

第一个格式:
try
{}
catch ()
{}
第二个格式:
try
{}
catch ()
{}
finally
{}
第三个格式:
try
{}
finally
{}
//记住一点:catch是用于处理异常。如果没有catch就代表异常没有被处理过,如果该异常是检测时异常。那么必须声明。
异常覆盖时的异常特点:
异常在子父类覆盖中的体现;
1,子类在覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法,只能抛出父类的异常或者该异常的子类。
2,如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
3,如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。
如果子类方法发生了异常。就必须要进行try处理。绝对不能抛。
练习:有一个圆形和长方形,都可以获取面积,对于面积如果出现非法的数值,视为获取面积出问题,问题通过一场来表现
public class ExceptionTest1 {
	public static void main(String[] args) {
		try {
			Rec r = new Rec(-1,5);
			r.getArea();
			Circle c = new Circle(-3);
			c.getArea();
		} catch (NoValueException e) {
			e.toString();
			e.printStackTrace();
		}
		System.out.println("over");

	}

}
class NoValueException extends Exception{
	NoValueException(String mess){
		super(mess);
	}
}
interface shape{
	void getArea();
}
class Rec implements shape{
	private int len;
	private int wid;
	Rec(int len,int wid) throws NoValueException{
		if(len<0||wid<0){
			throw new NoValueException("方形出现负值");
		}
		this.len = len;
		this.wid = wid;
	}
	public void getArea(){
		System.out.println(len*wid);
	}
}

class Circle implements shape{
	private int rad;
	private static final double  PI=3.14;
	Circle(int rad) throws NoValueException{
		if(rad<0){
			throw new NoValueException("圆形出现负值");
		}
		this.rad = rad;
	}
	public void getArea(){
		System.out.println(PI*rad*rad);
	}
}
异常小总结:
异常:
是什么?是对问题的描述。将问题进行对象的封装。
------------
异常体系:
Throwable
|--Error
|--Exception
|--RuntimeException

异常体系的特点:异常体系中的所有类以及建立的对象都具备可抛性。
也就是说可以被throw和throws关键字所操作。
只有异常体系具备这个特点。
--------------
throw和throws的用法:
throw定义在函数内,用于抛出异常对象。
throws定义在函数上,用于抛出异常类,可以抛出多个用逗号隔开。
当函数内容有throw抛出异常对象,并未进行try处理。必须要在函数上声明,都在编译失败。
注意,RuntimeException除外。也就说,函数内如果抛出的RuntimeExcpetion异常,函数上可以不用声明。
--------------
如果函数声明了异常,调用者需要进行处理。处理方法可以throws可以try。
异常有两种:
编译时被检测异常
该异常在编译时,如果没有处理(没有抛也没有try),编译失败。
该异常被标识,代表这可以被处理。
运行时异常(编译时不检测)
在编译时,不需要处理,编译器不检查。
该异常的发生,建议不处理,让程序停止。需要对代码进行修正。
--------------
异常处理语句:
try
{
需要被检测的代码;
}
catch ()
{
处理异常的代码;
}
finally
{
一定会执行的代码;
}

有三个结合格式:
1. try
{
}
catch ()
{
}

2. try
{
}
finally
{
}
3. try
{
}
catch ()
{
}
finally
{
}
注意:
1,finally中定义的通常是 关闭资源代码。因为资源必须释放。
2,finally只有一种情况不会执行。当执行到System.exit(0);fianlly不会执行。
--------------
自定义异常:
定义类继承Exception或者RuntimeException
1,为了让该自定义类具备可抛性。
2,让该类具备操作异常的共性方法。

当要定义自定义异常的信息时,可以使用父类已经定义好的功能。
异常异常信息传递给父类的构造函数。
class MyException extends Exception
{
MyException(String message)
{
super(message);
}
}

自定义异常:按照java的面向对象思想,将程序中出现的特有问题进行封装。
--------------
异常的好处:
1,将问题进行封装。
2,将正常流程代码和问题处理代码相分离,方便于阅读。
异常的处理原则:
1,处理方式有两种:try 或者 throws。
2,调用到抛出异常的功能时,抛出几个,就处理几个。
一个try对应多个catch。
3,多个catch,父类的catch放到最下面。
4,catch内,需要定义针对性的处理方式。不要简单的定义printStackTrace,输出语句。
也不要不写。
当捕获到的异常,本功能处理不了时,可以继续在catch中抛出。
try
{
throw new AException();
}
catch (AException e)
{
throw e;
}

如果该异常处理不了,但并不属于该功能出现的异常。
可以将异常转换后,在抛出和该功能相关的异常。

或者异常可以处理,当需要将异常产生的和本功能相关的问题提供出去,
当调用者知道。并处理。也可以将捕获异常处理后,转换新的异常。
try
{
throw new AException();
}
catch (AException e)
{
// 对AException处理。
throw new BException();
}

比如,汇款的例子。
异常的注意事项:
在子父类覆盖时:
1,子类抛出的异常必须是父类的异常的子类或者子集。
2,如果父类或者接口没有异常抛出时,子类覆盖出现异常,只能try不能抛。
四package
1.对类文件进行分类管理
2.给类提供多层命名空间
3.写在程序文件的第一行
4.类名的全称是   包名.类名
5.包也是一种封装形式
为了简化类名的书写,使用一个关键字,import.
import 导入的是包中的类。
建议,不要写通配符 * ,需要用到包中的哪个类,就导入哪个类。
建立定包名不要重复,可以使用url来完成定义,url是唯一的。
总结:
包与包之间进行访问,被访问的包中的类以及类中的成员,需要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  

jar包:
方便项目的携带
方便于使用,只要在classpath设置jar路径即可
数据库驱动,SSH框架等都是以jar包体现的





















  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值