java面向对象总结

时间:2024.3.31

面向对象

面向对象是一种思想,能让复杂的问题简单化,让我们角色从执行者变成指挥者,不要知道过程,只要知道结果。(一切皆对象。)

描述一个事物,其实就是在描述事物的属性和行为。

对象的特点在于封装数据,数据包含着属性和行为。

我们用类来描述一个事物,然后引用类来建立一个对象。

也可以在本类建立一个主函数来中创建本类对象,这个叫在本类中创建本类对象。

一般一个程序可以由很多个类组成,也可以有多个主函数,但一般有一个主函数就可以。

格式:引用类名 对象名=new 构造函数名(参数);

例:class DuiXiang{}

则建立对象为:DuiXiang mingZi=new DuiXiang();

如果要实现功能,则格式为:

mingZi.变量或函数名();

(string是java中的字符串。 String类是不可变的,对String类的任何改变,都是返回一个新的String类对象。 String 对象是 System.Char 对象的有序集合,用于表示字符串。String 对象的值是该有序集合的内容,并且该值是不可变的。)

面向对象主要的部分:(类和对象的关系,封装(机箱故事),继承,多态,构造函数,this,static,内部类,抽象类,接口)

面向对象之封装

函数是最小的封装体。类也是一个封装体。

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

每个成员变量通常都会对应两个访问方式:一个设置,一个获取。

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

因为语句都必须在函数内,所以,私有化后,再提供访问方式,就可以在访问方式的函数内实现变量控制。这样就提高代码的健壮性。

一般进行封装,要对类中的大部分属性都隐藏,最低权限是private。

类里有一个setXxx函数(一般返回值是void,直接获取,要带参数)和getXxx函数(有返回值类型,但一般没参数,getXxx之后一般用一个变量来接收:string x=p.getXxx
),那代表一定有一个私有化属性。

成员变量都有初始化值, 局部变量可以没有。

举例:

class  XueSheng

{

       private String name;

       public void setName(String name)//这个函数方便以后赋值

       {

              this.name=name;

       }

       public String getName()//这个函数是方便以后有需要调用的,比如以后要打印name的值

       {

              return name;

       }

构造函数:

函数名与类名一致,不用返回值类型,不可以用return,主要用来初始化对象。

对象一建立,就默认调用其构造函数。一个对象一建立,就有其默认的属性和行为。(如一个人刚出生就会呼吸,哭...)。

如果我们没有指认,那么类建立就会默认建一个构造函数(类名(){}),不然对象无法初始化,也就无法建立。(注意:只要我们有指认,那么就不会默认建构造函数)

其与普通函数的区别除了写法上之外:

1,构造函数只在对象建立时运行一次,不再运行了,而普通函数可以调用多次,另外,构造函数是用来初始化对象的,而一般方法是用来添加对象具备的功能。

何时我们要手动添加构造函数:当我们分析事物时,该事物存在一些特性或行为,那么我们就给其定义一个构造函数,如果有变量参与运算,那么我们就给构造函数定义一个参数。

构造函数写法举例:

class Person

{

       Person(String name,int age)

//注意:在新建一个对象时要加上参数进行区分,因为一个类可以放很多个构造函数。

//比如:Person p =new Person("fada",20)

       {

              this.name = name;

              this.age = age;

       }

      

构造代码块:

1,所有对象在建立时都先执行构造代码块初始化,再执行构造函数初始化。

2,作用:当所有对象有共性时,那么就可以定义一个构造代码块(例如:所有小孩先出来就是哭,然后才有其它的属性)

构造代码块的写法(就是在类里面用一个大括号)举例:

class Person

{

{

System.out.print("fada")

//这样一写,那么以后每次建立一个构造函数时便先初始化这个构造代码块

}

}

this关键字的用法

This在类中就是三个代表:代表对象的成员变量,在函数中代表对象调用函数,代表类中的构造函数。

格式:this.变量=变量;

this是用来区分局部变量和成员变量同名时的关键字,因为如果在构造函数里比如(name=name),那么其是赋值给他本身,而不是赋值给类里面的name。

何是用this?当定义类中的函数时,需要调用该函数的对象时,这个时候就用this来表示这个对象。

但凡本类功能内部使用到了本类对象,用this表示。

看到this就是有代表对象,代表哪个对象就看其所在功能被哪个对象调用。

这样就知道谁在参与运算。

例:

class Person

{

       private String name;

       Person(String name)

       {

              this.name = name;//this.name=p1.name;

}

}

class PersonDemo3

{

       public static void main(String[] args)

       {

              Person p1 = new Person("fada");

this的应用之定义类中函数的调用:当定义类中功能时,该函数内部要用到调用该函数的对象时,这时用this来表示这个对象。

              但凡本类功能内部使用了了本类对象,都用this表示。

例:

class Person

{

private String name;

       Person(String name)

       {

              this.name = name;//this.name=p1.name;

this.fada();//其实就==p1.fada();

//这里写这p1是因为p1这个对象在调用这个函数。一句话,谁调用它就在代表谁。

}

private int age;

Person(int age)

{

       this.age = age;

}

public void fada()

       {

              System.out.println("fada");

}

/*

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

       */

       public boolean compare(Person p)

       {

              return this.age==p.age;

       }

}

class PersonDemo

{

       public static void main(String[] args)

       {

              Person p1 = new Person(20);

              Person p2 = new Person(25);

//因为是两个人比,所以要先建立两人的对象

              boolean b = p1.compare(p2);

//这里定义了一个布尔型变量去接收p1调用compare函数的值

              System.out.println(b);

另一种this用法:格式this(变量)

用于构造函数间的相互调用,而且只能放在构造函数的第一行。

然后先初始化其this调用的构造函数,再初始化本身的构造函数。

其实this(变量);=new 构造函数名(变量);(因为所有构造函数名是一样的,都是重载函数,所以,通过变量来标记构造函数,用this去引用)

例:

class Person

{

       private String name;

       private int age;

      

       Person()

       {

              System.out.println("person run");

       }

       Person(String name)

       {

              This();

this.name =name;

       }

}

Static(静态)关键字:

static是一个修饰符:

三种修饰:修饰类的变量、方法和构造代码块。静态方法只能直接引用和访问静态变量和方法

注意(函数即方法,对象也叫实例)

有时你希望定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static 成员的最常见的例子是main( ) 。因为在程序开始执行时必须调用main() ,所以它被声明为static。   声明为static的变量称为静态变量或类变量。可以直接通过类名引用静态变量,也可以通过实例名来引用静态变量,但最好采用前者,因为后者容易混淆静态变量和一般变量。静态变量是跟类相关联的,类的所有实例共同拥有一个静态变量。 关键点:静态变量与实例变量的区别:静态变量也叫类变量,为所有对象所共有,所以一个对象的变量值改变,那么所有对象的值一起发生改变。

而实例变量则是各自独立的不受影响。

 声明为static的方法称为静态方法或类方法。静态方法可以直接调用静态方法,访问静态变量,但是不能直接访问实例变量和实例方法。静态方法中不能使用this关键字,因为静态方法不属于任何一个实例。静态方法不能被子类的静态方法覆盖。

特有属性随着对象存储于堆内存中,而static修饰后的属性,存在于方法区.

什么时候使用静态修饰符?

当对象中出现共享数据时,使用静态修饰。

但对象内的特有数据要定义成非静态存在于堆内存中。

而对于方法时:

当功能内部没有访问到非静态数据时,(即对象的特有数据)

那么可以使用静态修饰。

静态代码块:

用于给类做初始化的。不管有没有对象都执行,只要调用了类里面成员或方法,就会执行,而且优先于主函数,优先执行级别最高。

例:

class JingTai

{

       static int age;

       static String name;

       static//静态代码块初始化类的,所以最先运行。

       {

              System.out.println("name="+name);

       }

//下面是构造代码块,第二个运行

       {

              System.out.println("age="+age);

       }

       public static void jing(int x)//被对象调用,第三个运行。

       {

              x =age+1;//因为age是静态的,所以能调用

              System.out.println("x="+x);

       }

}

class FaDa

{

       public static void main(String[] args)

       {

              JingTai p =new JingTai();

              p.jing(2);

       }

      

}

文档注释:

文档注释有编译工具进行,具体一个要注意的地方是:类名前必须要有public修饰。要编译的方法名必须有public 修饰

javadoc注释标签语法
@author 对类的说明标明开发该类模块的作者
@version 对类的说明标明该类模块的版本
@see 对类、属性、方法的说明 参考转向,也就是相关主题
@param 对方法的说明对方法中某参数的说明
@return 对方法的说明 对方法返回值的说明
@exception 对方法的说明 对方法可能抛出的异常进行说明

命令是:javadoc -d 存放目录名称 -author -version 类名.java

/**

这是一个静态修饰符static的应用说明

@author 李四

@version V1.1

*/

/**

这是一个测试类

*/

public class JingTai

{

       /**

       空参数构造函数

       */

       /**

       age 一个整数型变量

       */

       public static int age;

       /**

       name 一个字符串型变量

       */

       public static String name;

       static

       {

              System.out.println("name="+name);

       }

       {

              System.out.println("age="+age);

       }

       /**

       打印x的值

       @param x 接收一个int型整数

       */

       public static void jing(int x)

       {

              x =age+1;

              System.out.println("x="+x);

       }

}

注意:main方法作为程序入口,应该在public的类Test中定义

设计模式:

做一个模式,使其能解决一类问题,这样,碰到类似的问题,直接套就可以了。

java23种设计模式:

举例:

单例设计模式:解决一个类在内存只存在一个对象。不再新生成。

思路:

1,为了避免其他程序过多建立该类对象。先禁止其他程序建立该类对象

2,还为了让其他程序可以访问到该类对象,只好在本类中,自定义一个对象。

3,为了方便其他程序对自定义对象的访问,可以对外提供一些访问方式。

步骤:

1,将构造函数私有化。

2,在类中创建一个本类对象。

3,提供一个方法可以获取到该对象

两种方式:

饿汉式

class Er

{

private Er(){};

private static Er e =new Er();

public static Er getEr()

{

return e;

}

}

懒汉式

class Er

{

private Er(){};

private static Er e =null;

public static Er getEr()

{

if(e==null)

e=new Er();

return e;

}

}

虽然懒汉式可以延迟加载对象,但为代码的简洁性和安全性,日常用的还是饿汉式。

继承

继承就是将两个类的共性描述提取出来,单独进行描述,从而简化代码,提高复用性。

格式:class 子类名 extends 父类名

关健字为extends :继承

判断两个类是否有所属关系,那么我们就继承一下,看父类所具有的内容属性,子类是否全都需要具备。如果是,那么他们所属关系成立,就是继承。

注意:千万不要为了获取其他类的功能,简化代码而继承。

必须是类与类之间有所属关系才可以继承。所属关系 is a。

例如:

class A

{

       //void demo1(){}

       void demo2(){}

}

class B

{

       //void demo1(){}

       void demo3(){}

}

我们可以让B继承下A,但发现,A中还具有demo2这个方法是B所不具备的,所以他们俩的继承关系不成立,但我们可以把两个类的共性提取出来,成为一个

class C

{

void demo1(){}

}

那么A和B就能够继承C,这样就实现在代码的简化和复用。

Java语言中:java只支持单继承,不支持多继承。

因为多继承容易带来安全隐患:当多个父类中定义了相同功能,

当功能内容不同时,子类对象不确定要运行哪一个。

但是java保留这种机制。并用另一种体现形式来完成表示。多实现。

java支持多层继承。也就是一个继承体系

如何使用一个继承体系中的功能呢?

想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。

通过了解共性功能,就可以知道该体系的基本功能。

那么这个体系已经可以基本使用了。

那么在具体调用时,要创建最子类的对象,为什么呢?

一是因为有可能父类不能创建对象,

二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。

简单一句话:查阅父类功能,创建子类对象使用功能。

聚集:has a

事物与事物的另一种关系,比如(类与类,对象与对象)

聚合:例如:一个班里的有很多学生,那么班级和学生就是聚合关系。就是包含。

组合:组合与聚合区别在于,组合各成员是不可分割的,否则会缺少功能,但聚合里的成员可以脱离,对整体没有影响。

子父类出现后,类成员的特点:

类中成员:

1,变量。

2,函数。

3,构造函数。

1,变量

如果子类中出现非私有的同名成员变量时,

子类要访问本类中的变量,用this

子类要访问父类中的同名变量,用super。

super的使用和this的使用几乎一致。

this代表的是本类对象的引用。

super代表的是父类对象的引用。

例如:

class Fu

{

       int num = 4;

}

class Zi extends Fu

{

       int num = 5;

       void show()

       {

              System.out.println(super.num);

//有super对象调用函数打印结果是4,没有打印结果是5

       }

}

子父类中的函数另一个特性:函数的重写(覆盖)

当子类继承父类,沿袭了父类的功能,这时不但可以保留父类的功能定义,还可以重写功能内容。

覆盖要注意的关健点:

1,子类覆盖父类,必须保证子类访问权限大于等于父类权限,才可以覆盖,否则编译失败。

(权限修饰符没设的时候为默认权限,介于public与private之间。)

例如:

class Fu

{

       void show()

       {

              System.out.println("fu show");

       }

}

class Zi extends Fu

{

       void show()

       {

              System.out.println("java");

//这里我即可以改变,也可以增加。增加时我们不用重写一遍父类函数的内容,只虽要super.函数名()就可以。

       }

2,静态只能覆盖静态。

注意:

重载:只看同名函数的参数列表。

重写:子父类方法要一模一样。

子父类中的构造函数之特点:

子类中的构造函数会默认调用父类中的函数中的默认构造函数,因为子类的构造函数默认第一行有一条隐式的语句 super();

但有几个地方要注意:

例:

class Fu 

{

       Fu()

注意:如果没有这一个空参数的构造函数,但又有我们指认的非空参数的构造函数,那么我们知道默认那个空参数构造函数也不会生成,这个时候子类就会编译失败。这个时候就不能让子类默认获取super();而要指认super(x

{

              num= 60;

              System.out.println("fu run");

       }

       Fu(int  x)

       {

              System.out.println("fu ...."+x);

       }

      

}

class Zi extends Fu

{

       Zi()

       {

              super();  //不管父类有几个构造函数,只要没有指认,那么就默认这一个super();

              //super(4);

System.out.println("zi run");

       }

       Zi(int x)

       {

              super();

              super(3);

              System.out.println("zi..."+x);

       }

}

调用构造函数用super();(括号里面是参数),而调用一般函数用super.函数名()

一个构造函数中只能要么有this要么有super,而且必须放在第一行

子类中至少会有一个构造函数会访问父类中的构造函数。

extends Objectjava中的顶极父类,也就是任何没标明父类的类的默认父类。

final : “最终”修饰符:

1,可以修饰类,函数,变量。

2,被final修饰的类不可以被继承作用:为了避免被继承,被子类复写功能。

3,被final修饰的方法不可以被复写

4,被final修饰的变量是一个常量只能赋值一次,既可以修饰成员变量,有可以修饰局部变量。

       当在描述事物时,一些数据的出现值是固定的,那么这时为了增强阅读性,都给这些值起个名字。方便于阅读。

       而这个值不需要改变,所以加上final修饰。作为常量:常量的书写规范所有字母都大写,如果由多个单词组成,单词间通过_连接

5,内部类定义在类中的局部位置上是,只能访问该局部被final修饰的局部变量。

例如:

final int x=4;那么x永远等于4,不可以被赋值,就成了常量,之所以不直接定常量,是因为要给数值起个名,增强阅读性,以后也好调用。

抽象

修饰符,abstract:只能修饰类和方法:

特点:

1,修饰的类不能创建对象(实例)。

2,修饰的对象只有功能,没有内容。

3,抽象方法和抽象类都必须被abstract关键字修饰,也就是抽象方法一定在抽象类中,

   但抽象类不一定要有抽象方法.

4,抽象类中的抽象方法要被使用,必须由子类复写起所有的抽象方法后,建立子类对象调用。

       如果子类只覆盖了部分抽象方法,那么该子类还是一个抽象类。因为抽象方法和抽象类都必须被abstract关键字修饰(如果只复写了一个,那么子类必然还继承了其它的抽象方法,根据抽象方法必须在抽象类中,则这个类还是个抽象类)。

应用:

1,建立不可创建对象的类。

2,如果子类中需要的方法内容不一样,但又同样都要这么方法,那么就可以创建一个抽象类。

例如:创建一个学校成员,有学生,有老师,都有姓名,年龄,都要上课,但老师上课是教学,学生上课是学习。所以可以这样写:

class XueXiao

{

       private String name;

       private int age

       XueXiao(String name,int age)

       {

              this.name = name;

              this.age = age;

       }     

       public abstract void work();//子类需要这个功能,但内容不一样,所以用抽象。

}

class Student extends Employee

{

Student(String name,int age)

{

       super(name,age);//直接调用父类构造函数。

}

       public void work()

       {

              System.out.println("shangke");

       }

}

class LaoShi extends Employee

{

       LaoShi(String name,int age)

       {

              super(name,age);//直接调用父类构造函数。

       }

       public void work()

       {

              System.out.println("laoshi");

       }

}

模版方法设计模式:

什么是模版方法呢?

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

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

abstract class GetTime

{

       public final void getTime()//这个类是不需要改变的,所以就用final最终修饰。

       {

              long start = System.currentTimeMillis();

              runcode();

              long end = System.currentTimeMillis();

              System.out.println("毫秒:"+(end-start));

       }

       public abstract void runcode();//这个函数主体要设成不确定,这样记算任何函数的运行时间:我只要把要算的函数定义成这个的内容就行了。所以设成抽象类的方法。

}

class SubTime extends GetTime

{

       public void runcode()

       {

              for(int x=0; x<4000; x++)

              {

                     System.out.print(x);

              }

       }

}

要调用计时这个功能,我们就在要在类中新健一个SubTime的对象。再调用getTime函数的就可以(SubTime类继承了父类,所以有getTime函数。)

接口:

接口:初期理解,可以认为是一个特殊的抽象类

       当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。

class用于定义类

关健字:interface 用于定义接口。

接口定义时,格式特点:

1,接口中常见定义:常量,抽象方法。

2,接口中的成员都有固定修饰符,(不写也会自动生成)。

       常量:public static final

       方法:public abstract

记住:接口中的成员都是public的。

接口:是不可以创建对象的,因为有抽象方法。

需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。

否则子类是一个抽象类。原因和抽象类一样,有抽象则为抽象类。

接口可以被类多实现,也是对多继承不支持的转换形式。java支持多实现。

1,类可以实现多个接口,用关健字:implements 如:

class Test implements JieKou,JieKou2

2,类继承后,仍可以实现多个接口,如:

class Test extends Demo implements JieKou,JieKou2

3,接口在可以实现多继承,如:

interface Test extends A,B

例:

abstract class Student

{

       abstract void study();学生都要学习,所以可以作为父类来给子类继承。

}

interface Smoking

{

       void smoke();//抽烟不是所有学生都会,所以,不可以继承,不然所有学生都抽烟了,所以定义为接口,让需要的类实现就行。

}

class ZhangSan extends Student implements Smoking

//继承后再实现,这样就实现了功能的扩展。

{

       void study(){}

       public void smoke(){}//记得要复写,因为父类是抽象的。

}

class Lisi extends Student

{

void study()

{

System.out.prtintln("study")

}

}

多态:

1,多态的体现

       父类的引用指向了自己的子类对象。

       父类的引用也可以接收自己的子类对象。

2,多态的前提

       必须是类与类之间有关系。要么继承,要么实现。

       通常还有一个前提:存在覆盖。

3,多态的好处

       多态的出现大大的提高程序的扩展性。

4,多态的弊端:

       提高了扩展性,但是只能使用父类的引用访问父类中的成员。

    如何要访问子类特有对象必须强制转换为子类对象。

abstract class Animal

{

       abstract void eat();

}

class Cat extends Animal

{

       public void eat()

多态还有一个前提:存在覆盖。不然没有意义,只是继承了一个空方法。

       {

              System.out.println("吃鱼");

       }

public void catchMouse()

但是只能使用父类的引用访问父类中的成员。因为父类中并没有catchMouse方法,所以多态无法实现catchMouse

       {

              System.out.println("抓老鼠");

       }

}

class Dog extends Animal

{

       public void eat()

       {

              System.out.println("吃骨头");

       }

}

public static void function(Animal a)//Animal a = new Cat();父类的引用指向了自己的子类对象。父类的引用也可以接收自己的子类对象。

前题:必须是类与类之间有关系。要么继承,要么实现。Animal是动物,Cat是它的子类。

{

       a.eat();

}

class DuoTaiDemo

{

       public static void main(String[] args)

       {

              function(new Cat());

function(new Dog());提高了扩展性,不用再去新建一个对象,再引用对象的功能。

       }

Object类:

是所有对象的直接后者间接父类.

该类中定义的是所有对象都具备的功能。

如果自定义类中需要的功能是Object含有的,那么没有必要重新定义,只要沿袭父类中的功能,建立自己特有比较内容,覆盖即可。

常用的有比较功能:

public boolean equals(Object obj)

//这里要是Object对象,所以这里相当于:Object obj =new 自定义类()

......这里写其自定义的内容,如果这里要有自定义类里的特有功能,那么要强转对象

格式是:自定义类 x = (自定义类)obj

内部类

特点:1,内部类可以直接访问外部类中的成员,包括私有。

           (原因:内部类中持有了一个外部类的引用,格式:外部类名.this

      2,外部类要访问内部类,必须建立内部类对象。

      3, 当内部类在成员位置上,就可以被成员修饰符所修饰。

       比如,private:将内部类在外部类中进行封装。

                static:内部类就具备static的特性。

              当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。

              在外部其他类中,新建立一个对象直接访问static内部类的非静态成员,但对象前

        用外类名修饰

                               new Outer.Inner().function()

              在外部其他类中,直接用类名来直接访问static内部类的静态成员,但类名前用外

        类修饰

              Outer.Inner.function();

       注意:当内部类中定义了静态成员,该内部类必须是static的。

                当外部类中的静态方法访问内部类时,内部类也必须是static的。

何时应用内部类:

     当描述事物时,事物的内部还有事物,该事物用内部类来描述。这个主要体               现一种类的优化思想。而且一般将内部类私有,而通过创建方法给外部调用。

例如:

 class Outer

{

       private int x = 3;要访问这个是:Outer.this.x

       class Inner//内部类

       {

              int x = 4;;//要访问这个是:this.x

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

       }

}

当内部类定义在局部时:

1,不可以被成员修饰符修饰

2,可以直接访问外部类中的成员,因为还持有外部类中的引用。

       但是不可以访问它所在的局部中的变量,只能访问被final修饰的局部变量。

例如:

class Outer

{

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

//注意:这里之所以可以,是因为out.method(7);进的是栈内存,用完后就自动消失了,out.method(8);重新加载了,所以尽管变量被final修饰但是依然可以。

       }

}

匿名内部类:

特点:

1,匿名内部类其实就是内部类的简写格式。

2,定义匿名内部类的前提:

       内部类必须是继承一个类或者实现接口。

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

4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。  可以理解为带内容的对象。

5,匿名内部类中定义的方法最好不要超过3个。

应用举例:

interface Inter

{

       void method();

}

class Test

{

       static Inter function()

       {

              return new Inter()

              {

                     public void method()

                     {

                            System.out.println("method run");

                     }

              };

       }

}

class InnerClassTest

{

       public static void main(String[] args)

       {            

Test.function().method();

}

}

异常:

把程序运行中出的问题通过java的类的形式进行描述,并封装成对象,这个对象的体现就是异常.

好处在于:将问题进行封装,从而将正常流程代码和问题处理代码相分离,方便于阅读。

异常有两种,严重的和不严重的。

对于严重的,java通过Error类进行描述。

       对于Error一般不编写针对性的代码对其进行处理。

对与非严重的,java通过Exception类进行描述。

       对于Exception可以使用针对性的处理方式进行处理。

无论Error或者Exception都具有一些共性内容。

比如:不正常情况的信息,引发原因等。

Throwable

       |--Error

       |--Exception

2,异常的处理

java 提供了特有的固定语句进行处理。

try

{

       需要被检测的代码;

}

catch(异常类 变量)

{

       处理异常的代码;(处理方式)

}

finally//这句可以没有。

{

       一定会执行的语句;通常用于关闭资源。(不管用了return,还是continue,还是break,其都会运行。

注意:当你在捕获到异常的处理代码里加上:
System.exit(0);
这样的话finally的代码块     是不会执行的。
捕获异常的规则是尽量优先捕获具体的异常。

System.exit(0)和System.exit(1)什么区别? 凡是非零都表示异常退出!0表示正常退出!

)

}

3,对捕获到的异常对象进行常见方法操作。

       String getMessage():获取异常信息。

在函数上声明异常。

便于提高安全性,让调用出进行处理。不处理编译失败

对多异常的处理。

1,声明异常时,建议声明更为具体的异常。这样处理的可以更具体。

2,对方声明几个异常,就对应有几个catch块。不要定义多余的catch块。

       如果多个catch块中的异常出现继承关系,父类异常catch块放在最下面

建立在进行catch处理时,catch中一定要定义具体处理方式。

不要简单定义一句 e.printStackTrace(),

也不要简单的就书写一条输出语句。

自定义异常:

必须是自定义类继承Exception,因为异常体系有一个特点就是异常类和异常对象都被抛出,他们要具备可抛性,而这个可抛性是Throwable这个体系中独有特点

只有这个体系中的类和对象才可以被throws和throw操作,二者区别是:

throws使用在函数上用,用来抛出异常,告诉调用者这里有可能会出现异常。throw使用在函数内用来抛出异常对象让调用者处理。

    throws后面跟的异常类。可以跟多个。用逗号隔开。

throw后跟的是异常对象

Exceptoin中有一个特殊的子类异常RuntimeException运行时异常。

    如果在函数内容抛出该异常,函数上可以不用声明,编译一样通过。

    如果在函数上声明了该异常。调用者可以不用进行处理。编译一样通过;

之所以不用在函数声明,是因为不需要让调用者处理,当该异常发生,希望程序停止,

对代码进行修正。

自定义异常时,如果该异常的发生,无法处理让其再继续进行运算,必须修正代码,就让自定义异常继承RuntimeException,如可以处理,则继承Exception

对于异常分两种:

1,编译时被检测的异常,那么不要么就catch处理它,不然就必须声名。

2,编译时不被检测的异常(运行时异常。RuntimeException以及其子类)

应用举例:

人用电脑办公。

    比如问题是

       电脑蓝屏:重启可以修正错误,继续上班,则继承Exception

       停电了:无法修正错误,只能停下来等电力供应恢复。

要对问题进行描述,封装成对象。

class LanPingException extends Exception

{

       LanPingException(String message)

       {

              super(message);

//直接调用父类方法,用来返回此 throwable 的详细消息字符串

       }

}

class TingDianException extends RuntimeException

{

       TingDianException(String message)

       {

              super(message);

       }

}

class Computer

{

       private int state = 2;

       public void run()throws LanPingException

       {

              if(state==2)

                     throw new LanPingException("蓝屏了");

              if(state==3)

                     throw new TingDianException(" 停电了");

              System.out.println("电脑运行");

       }

       public void reset()

       {

              state = 1;

              System.out.println("电脑重启");    

       }

}

class Person

{

       private String name;

       private Computer cmpt;

       Person(String name)

       {

              this.name = name;

              cmpt = new Computer();

       }

       public void prelect()

       {

              try

              {

                     cmpt.run();  

//人要调用run(),所以其接受了异常,其要么抛出,要行么处理。          

              }

              catch (LanPingException e)

              {

                     System.out.println("电脑蓝屏啦");

                     cmpt.reset();

              }

              System.out.println("办公");

       }

}

class ExceptionTest

{

       public static void main(String[] args)

       {

              Person t = new Person("人");

                     t.prelect();    

       }

}

异常的处理要注意的关健点:

       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,如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。

3,如果父类或者接口的方法中没有异常抛出,那么子类在覆盖方法时,也不可以抛出异常。

       如果子类方法发生了异常。就必须要进行try处理。绝对不能抛。

package包

包的作用:

可以将源文件与class文件分离,有利于安全性。也可以打包并可以直接操作。

两个关健字

package 用来标识class文件其属于哪个包,放于代码的最上面:package 包名(包名全部小写)

import 用于导入,就是要以把包下面的具体的一个类导入,(例如:import.a.b....)以及可以把包下面所有的类导入(例如:import.a.*;)

例:

package bao2;

import bao1.Test;

class Test1

{

       public static void main(String[] args)

       {

              Test a = new Test();

              a.show();

              System.out.println("fada test1");

       }

}

编译格式:

到源文件目录:javac -d e:\myclass Test.java

注意:如果包与包之间有调用,那么用set classpath=要访问的包的目录。

要注意的问题:

类名的全名是:包名.类名,如果要不用,那么就必须import导入功能。

需要设置classpath,告诉jvm去哪里找指定的packa包。

有了包,范围变大,一个包中的类要被访问,必须要有足够大的权限,所以被访问的类要被public修饰。

类公有后,被访问的成员也要公有才可以被访问。

总的来说:包与包之间进行访问,被访问的包中的类以及类中的成员,需要public修饰。

protected(保护权限):不同包中的子类还可以直接访问父类中被protected权限修饰的成员。

包与包之间可以使用的权限只有两种,public  protected

             public   protected       default     private

同一个类中     ok         ok             ok          ok

同一个包中     ok         ok             ok

子类           ok         ok            

不同包中       ok

jar

方便携带和使用,在classpath中设制好jar路径就可以了。数据库驱动,SSH等都以jar包形式体现。

编译格式:

jar -cf jar包名 package名1 package名2 package名3 .........

如:jar -cf fada.jar bao1 bao2(注意:要cd到pack包所在目录)

直接运行jar包内的文件,格式:

之前先set classpath=jar包所在目录\jar包名

如:set classpath = e:\myclass\fada.jar

编译格式:java bao2.Test1

继承

何为继承,有何作用

继承就是将两个类的共性描述提取出来,单独进行描述,从而简化代码,提高复用性。

格式:class 子类名 extends 父类名

关健字为extends :继承

判断两个类是否有所属关系,那么我们就继承一下,看父类所具有的内容属性,子类是否全都需要具备。如果是,那么他们所属关系成立,就是继承。

注意:千万不要为了获取其他类的功能,简化代码而继承。

必须是类与类之间有所属关系才可以继承。所属关系 is a。

例如:

class A

{

       //void demo1(){}

       void demo2(){}

}

class B

{

       //void demo1(){}

       void demo3(){}

}

我们可以让B继承下A,但发现,A中还具有demo2这个方法是B所不具备的,所以他们俩的继承关系不成立,但我们可以把两个类的共性提取出来,成为一个

class C

{

void demo1(){}

}

那么A和B就能够继承C,这样就实现在代码的简化和复用。

Java语言中:java只支持单继承,不支持多继承。

因为多继承容易带来安全隐患:当多个父类中定义了相同功能,

当功能内容不同时,子类对象不确定要运行哪一个。

但是java保留这种机制。并用另一种体现形式来完成表示。多实现。

java支持多层继承。也就是一个继承体系

如何使用一个继承体系中的功能呢?

想要使用体系,先查阅体系父类的描述,因为父类中定义的是该体系中共性功能。

通过了解共性功能,就可以知道该体系的基本功能。

那么这个体系已经可以基本使用了。

那么在具体调用时,要创建最子类的对象,为什么呢?

一是因为有可能父类不能创建对象,

二是创建子类对象可以使用更多的功能,包括基本的也包括特有的。

简单一句话:查阅父类功能,创建子类对象使用功能。

多线程

线程:每一个进程都有一个执行顺序,这个顺序就是一个独立的控制单元,这个独立的控制单元就是线程,线程在控制着进程的执行。

由一个Thread类来对这类事物进行描述。

自定义一个进程的方法(1):

定义一个类继承Thread类,并且复写Thread类中的run方法,将自定义代码储存在run方法中,让线程运行。最后通过创建一个线程的对象,通过调用线程的start()方法,来启动线程并执行run方法。

例:

class Xian extends Thread

{

       public void run()

       {

              for(int x=0; x<100; x++)

                     System.out.println("xiancheng run----"+x);

       }

}

class Cheng

{

       public static void main(String[] args)

       {

              Xian d = new Xian();//创建一个Thread类或其子类的对象就是建立一个线程。

              d.start();//开启线程并执行该线程的run方法。

              //d.run();//如果这样写仅仅是对象调用方法。而线程创建了,并没有运行。

       }

}

线程都有自己默认的名称,因为其有setName和getName方法。

默认为:Thread-编号 该编号从0开始。

设置线程名称:setName或者构造函数。

例:Test(String name)

       {

              super(name);//直接调用父类方法

       }

创建对象设置名字:Test a1 = new Test("xiancheng1");   Test a1 = new Test("xiancheng2");

通过static Thread currentThread()方法获取当前线程对象,再通调用getName()方法获取线程名称。

如:System.out.println((Thread.currentThread().getName()+" run..."+x);

创建线程的第二种方式:

步骤:

1,定义类实现Runnable接口

2,覆盖Runnable接口中的run方法。

       将线程要运行的代码存放在该run方法中。

3,通过Thread类建立线程对象。

4,将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数。

5,调用Thread类的start方法开启线程并调用Runnable接口子类的run方法。

实现方式和继承方式有什么区别呢?

实现方式好处:避免了单继承的局限性。

所以定义线程尽可能使使用实现方式。

两种方式区别:

继承Thread:线程代码存放Thread子类run方法中。

实现Runnable,线程代码存在接口的子类的run方法。

例:

class Ticket implements Runnable//extends Thread

{

       private  int tick = 100;

       public void run()

       {

              while(true)//让其循环

              {

                     if(tick>0)

                     {

                            System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);

                     }

              }

       }

}

class  TicketDemo

{

       public static void main(String[] args)

       {

              Ticket t = new Ticket();

              Thread t1 = new Thread(t);

//创建了一个线程;Thread里默认有一个构造方法用来接收Runnable对象。

这样一来Thread对象里面就有了Ticket对象。就能运行自定义run方法。

              Thread t2 = new Thread(t);//创建了一个线程;

              Thread t3 = new Thread(t);//创建了一个线程;

              Thread t4 = new Thread(t);//创建了一个线程;

              t1.start();

              t2.start();

              t3.start();

              t4.start();

}

}

同步代码块:

作用:用于解决多线程的安全问题。

格式:

synchronized(对象)

{

       需要被同步的代码,仅放被线程执行的易出现问题的那个部分,不要多放。

}

对象如同锁。持有锁的线程可以在同步中执行。

没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁。

同步的前提:

1,必须要有两个或者两个以上的线程。

2,必须是多个线程使用同一个锁。

3,必须保证同步中只能有一个线程在运行。

其弊端:多个线程需要判断锁,较为消耗资源,

举例:

class Ticket implements Runnable

{

       private  int tick = 1000;

       Object obj = new Object();

       public void run()

       {

              while(true)

              {

                     synchronized(obj)//这里虽要一个对象用于标识锁。

                     {

                            if(tick>0)

                            {

                                   try{Thread.sleep(10);}catch(Exception e){}

                            System.out.println(Thread.currentThread().getName()+"....sale : "+ tick--);

                            }

                     }

              }

       }

}

同步函数:

函数用synchronized修饰后就可以实现同步了。同步函数的锁是this,也就是代表调用这个函数的对象。

如果同步函数被静态修饰后,因为静态方法中也不可以定义this,并且静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。

所以静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class

格式:类名.class  该对象的类型是Class

举例:

写一个延迟加载的单例设计模式:

class  DanLi

{

       private static DanLi s = null;

       private DanLi(){}

       private static DanLi getInstance()

       {

//用同步解决多线程用懒汉式的安全隐患,同步锁用的对象是该类的字节码对象。

//用双重判断解决多线程效率问题。关健在于用以双重判断不用再每次都走同步操作。

              if(s==null)

              {

                     synchronized(DanLi.class)

                     {

                            if(s==null)

                                   s = new DanLi();

                     }

              }

              return s;

       }

}

死锁:

同步中嵌套同步。

线程间通讯

就是多个线程在操作同一个资源,但是操作的动作不同。

需要用到的方法:

wait();注意:其会抛出一个异常,所以一定要try{this.wait();}catch(Exception e){}

notify();解除线程池中最先等待的那个wait,就是看谁等待时间最长,依次类推下去。

notifyAll();解除所有的wait等待。

1,这三个方法都使用在同步中,因为要对持有监视器(锁)的线程操作,而只有同步才具有锁。

2,这三个方法都属于Object类中,因为这些方法在操作同步中线程时,都必须要标识它们所操作线程仅有的锁,只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。

不可以对不同锁中的线程进行唤醒。也就是说,等待和唤醒必须是同一个锁。

而锁可以是任意对象,所以可以被任意对象调用的方法定义Object类中。

举例:

生产者和消费者实例:

jdk1.5中对synchronized同步功能作了升级,把其替换成了Lock操作,用lock.lock();加锁,用lock.unlock();来解锁。同时把等待唤醒机制中wait(),notify(),notifyAll(),功能封装成了一个Condition对象,用lock.newcondition()创建对象,并且用condition.await();及condition.signal();和condition.signalAll(),来实现等待,唤醒功能!而这个的优点就在于一个lock锁可以创建N多个condition对象,这就可以实现等待和唤醒指定对象。

public  void set(String name)throws InterruptedException

       {

              lock.lock();加锁

              try

              {

                     while(flag)

                            condition_pro.await();//等待

                     this.name = name+"--"+count++;

                     System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);

                     flag = true;

                     condition_con.signal();唤醒特定对象。

              }

              finally

              {

                     lock.unlock();//释放锁:这个动作一定要执行。

              }

       }

中断线程

Thread类中有一个方法叫做interrupt();中断线程。

其主要作用是强制唤醒处于wait()和sleep()状态中的线程,并抛出一个InterruptedException异常。所以使用时要进行处理:用try{},catch(InterruptedException e){}

守护线程

setdaemon(ture)方法:守护线程,也就是后台线程,要在线程运行前加载。

特点为:当只剩下守护线程时,java虚拟机自动退出。

应用:输入出输出,不再输入了,输出就没有意义,所以可以把输出线程标记为守护线程,那么输入线程也就是前台线程运行结束,这个时候输出线程也会自动结束。

等待线程中止

join();

一旦线程调用它,那么主线程便会释放cpu执行权,直到调用它的线程运行完,并抛出一个异常,主线程才会激活继续运行。这个可以用来插入线程。

提高权限优先级

setPriority();方法,总共有1—10,因为是常量,所以给一个名称,例如给最高的优先级。则为线程名.setPriority(Thread.MAX_PRIORITY);

暂停当前执行的线程,让其它线程运行。

Thread.yield();这样可以让线程交替运行,平均执行权。

当一个主函数里有多个循环或运行程序,则可使用匿名内部类封装成多个线程。这样程序高效,不干扰。

更多相关推荐:
java面向对象总结(绝对经典)

主要内容学习方法介绍面向对象思想介绍类与对象关系封装概念1学习方法介绍四问法什么有什么特点怎么用demo什么时候用test2面向对象与面向过程的区别面向过程强调的是功能和行为面向对象强调的是具有某种功能的对象即...

java面向对象编程总结

java之面向对象编程本章内容编程语言的发展面向过程的设计思想面向对象的设计思想对象和类的概念面向对象编程原则对象和引用Java类的定义构造函数对象的创建和使用this关键字static关键字package和i...

Java面向对象总结

1static修饰的成员变量和方法既可以通过类访问也可以通过实例访问普通的方法和成员变量只能通过实例访问原因类只有被实例化后普通的成员变量才会分配内存所以类无法直接访问普通成员变量只能通过实例访问2方法的参数传...

java面向对象精华总结

Java面向对象精华总结面向对象是相对面向过程而言的面向过程强调的是功能行为面向对象是将功能封装进对象强调具备了功能的对象面试官若问什么是面向对象开放式问题回答必须有自己的体会1面向对象是一种思想可以使复杂的问...

java面向对象总结

面向对象1基本概念面向对象是一种思想它专注于对象也就是人们要进行研究的任何事物面向对象更加有利于处理问题并且使程序更具有灵活性三个特点1封装性两个方面保护信息把对象的属性和行为看作一个整体2继承性主要描述反映事...

java面向对象总结

1.子类与父类的关系?子类继承父类但不能继承private成员,子类只能有一个父类,如果省略了extends,子类的父亲就是object,子类继承了父类和祖先的成员,子类可以添加新的成员变量和方法,也可以隐藏父…

java面向对象程序设计基础知识总结

1含有main方法的类称为主类一个java文件中可以有多个类但只能有一个主类2转义字符对于和需在前面加上即用chara3939b3939表示n表示回车换行t表示水平制表b表示退格v表示水平制表r表示回车a表示警...

Java面向对象技术总结(含代码)

Java面向对象技术总结1什么是面向对象思想从世界观的角度可以认为面向对象的基本哲学是认为世界是由各种各样具有自己的运动规律和内部状态的对象所组成的不同对象之间的相互作用和通讯构成了完整的现实世界因此人们应当按...

Java 面向对象16种设计原则总结版

Java面向对象16种设计原则一类的设计原则1依赖倒置原则DependencyInversionPrincipleDIP2里氏替换原则LiskovSubstitutionPrincipleLSP3接口分隔原则I...

Java面向对象编程习题总结

第一章面向对象开发方法概述1面向对象的软件开发有哪些优点1把软件系统看成是各种对象的集合这更接近人类的自然思维方式2软件需求的变动性往往是功能的变动而功能的执行者对象一般不会有多大的变化比结构化更稳定3对象包括...

学习心得《面向对象》

面向对象课程学习心得这学期的面向对象课程对我来说是收获匪浅的一门课通过老师课件的讲解自己一些相关书籍的阅读和实践作业的完成逐步对课程有了由浅及深的认识面向对象ObjectOrientedOO是一门以实践为主课程...

C++面向对象总结

一简答题1什么是类什么是对象对象与类的关系是什么答类就是相同的数据和相同的一组对象的集合即类是对具有相同数据结构和相同操作的一类对象的描述对象是描述其属性的数据以及对这些数据施加的一组操作封装在一起构成的统一体...

java面向对象总结(24篇)