黑马程序员 面向对象(OOP)学习笔记

来源:互联网 发布:淘宝合作平台 编辑:程序博客网 时间:2024/05/16 19:21

----------- android培训java培训期待与您交流! ------------

面向对象

1、面向对象是什么?

答:面向对象是一种(基于面向过程的)设计思想。

2、面向对象设计思想有何用?

答:用于解决现实世界中的问题。(即用软件系统来实现)

3、面向对象设计思想如何用?

答:以现实世界中客观存在的事物为中心来构造软件系统,并且在构造的过程中尽可能的运用人类的自然思维方式

 

面向过程:先分析出解决问题的步骤,然后按照步骤一步一步实现。

强调的是功能行为。

面向对象:分析出类和对象,以及其之间的关系。

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

 

一个经典的问题:如何将大象装进冰箱里。

面向过程的思想:1、打开冰箱;2、将大象存入冰箱;3、关上冰箱

面向对象的思想:1、冰箱.打开;2、冰箱.存储;3、冰箱.关闭

 

面向对象的思想将具体操作者提升到了指挥者的角色。

 

名词提炼法:得出类(或属性)

面向对象三个基本特性:封装、继承、多态。

 

面向对象开发过程:找对象使用;没有对象,才自己创建。

 

开发工作:找对象、建立对象、使用对象、维护对象间的关系。

 

类与对象

类:对生活中事物的描述(包括概念上的事物)。

对象:类的实例。

 

如图:生产汽车的图纸就相当于类(用于描述汽车这种事物的共性特征);生产出来的一个一个的汽车就是类的实例,即对象

 

定义类,就是在描述事物,描述事物的属性和行为。属性和行为被称为类中的成员;成员变量和成员方法。

 

成员变量和局部变量的区别:

1、作用范围:成员变量,作用于整个类中;局部变量,作用于函数或语句块中。

2、在内存中的位置:成员变量,在堆内存中,随着对象的存在而存在;局部变量,在栈内存中,局部块执行完,即在内存中消失。

 

匿名对象:对象的简写形式。

        两种使用情况:1、当对对象的方法只进行一次调用时。2、作为实际参数进行传递时。

 

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

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

       原则:不需要对外提供的内容都隐藏起来。

 

private,权限修饰符的一种,是类成员(成员变量,成员方法)修饰符,私有后只在本类可访问。是封装的一种体现形式。

 

对外提供公共访问方式的好处:可以在访问方式中添加逻辑判断等语句,对要访问的数据进行操作,提高了代码的健壮性。

 

构造函数:特点:1、与类名相同;2、不可定义返回值类型、不可以写return语句。

                 作用:给对象进行初始化。

 

什么时候定义构造函数?

当分析事物时,该事物具备一些特性或者行为,将其定义在构造方法中。 

 

对象一创建,就会调用相应的构造函数, 多个构造函数以重载的形式存在。

当一个类中没有定义构造函数时,jvm会为该类自动添加一个空参数的构造函数。

若定义了构造函数,就不添加默认构造函数。

默认构造函数的访问权限和所属类一致。

 

构造函数和一般函数的区别:

1、写法上

2、对象一建立,构造函数只能运行一次;而一般函数可被该对象调用多次。

 

构造代码块

作用:给对象进行初始化,定义的是不同对象共性的初始化内容。对象一建立就运行,而且优先于构造函数。

 

构造代码块与构造函数的区别:

构造代码块是给所有对象初始化,而构造函数是给相应的对象初始化。

 

this:本类对象的引用。

this语句:用于构造函数之间进行互相调用。只能定义在构造函数的第一行。

 

static :用于修饰成员(成员变量和成员函数)

被修饰的成员特点:

1、随着类的加载而加载,优先于对象存在。2、被所有对象所共享。3、可以直接被类名调用。

注意:①静态方法只能访问静态成员。②静态方法中不能出现this和super关键字(这两个关键字是对象创建后才有的)。③主函数是静态的。

 

实例变量和类变量的区别:

1、内存中的位置:实例变量随对象的创建而存在于堆内存中;而类变量随着类的加载而存在于方法区中。

2、生命周期:类变量随着类的消失而消亡;实例变量随着对象的消失而消失。

 

静态的利弊:

利:所有对象共享一数据,省内存;能直接被类名调用,使用方便。

弊:生命周期过长;出现访问局限性。

 

何时定义静态?

静态变量的定义:多个对象存在共享数据,可以定义为静态。

静态方法的定义:若方法中没有访问对象的特有数据或方法时,可以定义为静态。

 

静态代码块

static {

        语句;

}

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

 

 

对象初始化过程

Person p = new Person("Zhangsan", 20);1、类加载器找到Person.class文件并加载到内存中。2、执行该类的static代码块,若有,给类进行初始化。3、在堆内存中开辟空间,分配内存地址。4、在堆内存中建立对象的特有属性,并进行默认初始化。5、对属性进行显示初始化。6、对对象进行构造代码块初始化。7、对对象进行构造函数初始化。8、将内存地址赋值给栈内存中的p变量。


继承

特点:1、提高了代码的重用性。 2、让类与类产生了关系,是多态的前提。

继承的类与类之间必须有所属关系。A is B   如Student extends Person;学生是人 

 

java只支持单继承

避免了多继承带来的安全隐患:当多个父类定义了相同的功能时,功能内容不同时,子类对象不确定要运行哪一个。

java保留了这种机制,用多实现来完成。

java支持多层继承,即继承体系。

 

javaAPI使用原则:查阅父类功能,创建最子类对象使用功能。

原因:1、父类定义的是该体系中的共性的功能 2、父类有可能不能创建对象 3、创建子类对象可以使用更多的功能。(包括特有的和共性的)

 

            |---------    聚集:球员和球队之间。(原则上可拆分)

聚合:|

            |---------    组合:人手和人之间。(原则上不能拆分)

 

聚合:A是B的一部分。据说设计时要分开。

 

super:父类对象的引用。

super关键字的使用方式同this。

 

覆盖:(重写Override)

1、子类覆盖父类时,子类权限必须 >= 父类权限,否则编译失败。

2、静态只能覆盖静态。

 

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

重写:子父类方法除权限修饰符外,其它部位要一模一样。

 

子类实例化过程

子类在调用构造方法进行初始化时,会先调用其父类的构造函数。默认情况下,子类所有的构造函数的第一句隐藏着一条super()语句来访问父类的无参构造函数。

可以手动定义super()来指定要访问的父类构造函数。super()语句也是放在构造函数的第一行。

父类中的数据,子类可以直接获取,所以子类在创建对象时,需要先查看父类如何对这些数据初始化的,可避免相同数据的重复定义。

子类中至少有一个构造函数会访问父类的构造函数。(有其子,必先有其父)

 

final关键字

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

2、被final修饰的类不能被继承。

3、被final修饰的函数不能被重写。

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

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

 

抽象类

多个类中出现相同功能,内容不同。这时可以进行向上抽取,只抽取功能定义,不抽取功能主体。

1、抽象方法一定在抽象类中。

2、抽象的方法和类必须被abstract修饰。

3、抽象类不可以用new创建对象。因为调用抽象方法没有意义。

4、抽象方法必须被子类重写后,才能由子类对象调用。如果子类只覆盖了部分抽象方法,那该子类还是抽象类。

特殊:抽象类中可以不定义抽象方法,这样做只是不希望其被创建对象。

抽象类和一般类的不同之处:1、抽象类可以有抽象方法。2、抽象类不能创建对象。

 

模板方法设计模式

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

那么就将确定的部分定义为final,不让子类重写;而以抽象形式暴露出不确定的部分,由子类完成重写。

例如:

//获取代码运行时间的模板设计模式abstract class GetTime {public final void getTime() {long startTime = System.currentTimeMillis();runCode();long endTime = System.currentTimeMillis();System.out.println("毫秒:" + (endTime - startTime));}public abstract void runCode();}


接口:(interface)

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

成员常量:public abstract final

成员方法:public abstract

接口的出现将“多继承”的另一种体现形式体现出来,即“多实现”。

 

接口不能创建对象,因为有抽象方法。

需要被子类实现其所有抽象方法后,子类才能实例化,否则子类也是一个抽象类。

接口可以被类多实现。

 

接口的特点:

1、接口是对外暴露的规则。2、接口是程序的功能扩展。3、接口可以用来多实现。4、类与接口之间是实现关系,而且类在继承一个类的同时实现多个接口。5、接口和接口之间可以有继承关系。

 

多态

某一类事物的多种存在形态。

如:人:男人、女人。

 

多态的体现:父类引用指向子类对象。(向上转型)

多态的前提:必须是类与类之间有关系。继承或实现。

多态的好处:提高了程序的扩展性。


转型:强转称为向下转型。

多态自始至终都是子类对象在做着变化。

 

多态中

非静态成员函数的特点:编译看左边,运行看右边。(动态绑定)

非静态成员变量的特点:编译、运行时期都看左边。

静态成员函数和静态成员变量的特点:编译、运行时期都看左边。(静态绑定)

 

内部类

当描述事物时,事物的内部还有的事物就用内部类来描述。(内部事物在使用外部事物的内容)比如:身体内的心脏就可以用内部类描述。

 

访问特点:1、内部类可以直接访问外部类中的成员,包括私有成员 (内部类中持有外部类的引用,外部类名.this)。

2、外部类要访问内部类中的成员必须要建立内部类的对象。

 

访问格式:

1、当内部类定义在外部类的成员位置上:

        ①且非私有时,可以在外部其它类中直接创建该内部类对象,格式:Outer.Inner in = new Outer().new Inner();

        ②可以被成员修饰符修饰,如private(将内部类在外部类中进行封装)、static(内部类就具备了static的特性)

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

        ④在外部其它类中,如何访问static内部类的非静态成员?        new Outer.Inner().method();

        ⑤在外部其它类中,如何访问static内部类的静态成员?        Outer.Inner.method();

 

注意:1、当内部类定义了静态成员,该内部类必须是static的。        2、外部类中的静态方法只能访问静态内部类。

 

2、当内部类定义在外部类的局部位置上时:

        ①不可以被成员修饰符修饰

        ②可以直接访问外部类中的成员(还持有外部类的引用)

        ③不能访问它所在局部中的一般变量,只能访问被final修饰的局部变量。

 

匿名内部类:内部类的简写形式

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

2、格式:new 父类或接口() {定义子类的内容}

3、其实就是一个匿名子类对象。(可理解为带内容的对象)

4、匿名内部类中的方法最好不要超过三个。(否则就失去了意义)

 

 

异常

异常:程序在运行时出现不正常情况。

异常由来:问题也是现实生活中的一个具体事物,java也将其描述并封装成了对象。

 

          |———— 严重:用Error描述(不编写针对性的代码对其处理)(错误)

问题 |

          |———— 非严重:用Exception来描述(编写代码进行处理)(异常)

 

这两个类的父类:Throwable

 

异常处理

try {需要被检测的代码;} catch(异常类 变量) {处理方式;} finally {一定会被执行到的语句;}


catch常见处理方式:1、System.out.println(e.toString()); 2、System.out.println(e.getMessage()); 3、System.out.println(e.printStackTrace());

4、在方法体上声明抛出异常throws Exception 5、在catch块中throw new RuntimeException();

 

finally通常用于关闭资源。

 

异常处理其它格式:

1、try{} catch() {} 2、try{} finally{};其中第二种格式,没有catch语句,说明没有被处理,必须在函数上声明。

 

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

 

对异常的处理:

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

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

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

 

自定义异常

对项目中特有问题,进行自定义异常封装。

class NegativeException extends Exception{private String msg;NegativeException(String msg) {super(msg);}public String getMessage() {return msg;}}


为何要继承Exception:异常体系的类都具备可抛性。具备可抛性才能throw、throws

 

总结throw、throws的区别:

1、throw使用在函数内;throws使用在函数上。

2、throw后跟异常对象;throws后跟异常类。

 

RuntimeException 运行时异常:

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

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

 

自定义异常继承RuntimeException:因为在运行时,出现了无法继续运算的情况,希望停止程序后,对代码进行修正。

 

 异常在子父类覆盖中的体现:

1、子类在覆盖父类时,子类只能抛出父类的异常或父类异常的子类

2、若子类有额外的异常,则必须try{}catch(){}处理,不能抛出。

 

包(package):

1、对类文件进行分类管理

2、给类提供多层命名空间

3、写在程序的第一行

4、类名的全称:包名.类名

5、包也是一种封装形式

 

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

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

包与包之间修饰权限只有两种:public、protected

 

java权限 publicprotecteddefaultprivate同一类中okokokok同一包中okokok子类okok不同包中ok  

 

jar包:

1、方便项目携带

2、方便于使用,只要在classpath设置jar路径即可

3、数据库驱动,SSH框架等都是以jar包体现的。

 

 

 

----------------------- android培训java培训、期待与您交流! ----------------------

 详情请查看:http://edu.csdn.net/heima