面向对象的三大特征

说面向对象,则不得不提面向过程。面向对象的思想,正是面向过程思想的发展,是对它的突破。举个例子,你需要一所房子,有100rmb,这时你怎么做?你有两种选择:1,用这些钱去买地皮,买原材料,然后自己一个人盖房子;2,找开发商开发好的房子,直接选购。第一种方式,是面向过程;第二种就是面向对象。很明显,在面向对象的过程中,对于需要房子这个需求,你从面向过程中的执行者,变成了指挥者(或调用者);你不需要了解这个需求解决的具体细节,你只需要找一个能帮你解决问题的对象就行了。

       从功能封装的角度讲,面向对象最基本的功能封装单元跟面向过程一样也是函数,但面向对象可以将多个联系紧密的函数封装在一起,形成类,当你需要某个功能,只需要利用这个类建立一个对象,拿对象来调用这个功能就行了。

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

面向对象的开发,形象地讲就是找对象使用,如果没有对象,就建立一个。

程序员要做的就是:找对象,建立对象,使用对象,维护对象之间的关系。

类与对象的关系

       类是对现实世界事物的抽象描述,它的成员变量对应事物的属性,它的成员方法对应事物的行为。类的一个实例,即对象,对应现实世界事物的一个个体。

      成员变量与局部变量的不同:1.作用域不同,成员变量整个类中有效局部变量离它最近的一对{ }内有效;2内存中的位置不同,成员变量位于堆内存,局部变量位于栈内存

 

不同点

成员变量

局部变量

作用域

整个类中有效

离它最近的一对{ }内有效

内存中的位置

堆内存

栈内存

 

        匿名对象:匿名对象,可以调用属性但没有意义;调用方法有意义,但只能调用一次,若对一个对象进行多次成员调用必须给该对象建立引用;另外还可以作为参数传递给函数。

(强引用,弱引用,软引用,虚引用)写缓存的时候。

第一个特征:封装

 

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

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

封装的原则:将不需要对外提供的内容都隐藏起来。把属性都隐藏,提供公共方法对其进行访问。

private关键字:私有,权限修饰符,用于修饰类中的成员,私有只在本类中有效。

构造函数

与一般函数相比,它的特点:函数名与类名相同,不用定义返回值类型,不可以写return语句;构造函数是在对象一创建时就立刻运行,并给对象初始化,一个对象的构造函数只运行一次,而函数可以通过对象调用多次运行。

它的作用是给对象进行初始化。

注意:若没有自定义构造函数,系统会给类添加一个默认的空参构造函数,它的权限跟类的权限一致;如果定义了构造函数,系统则不再添加默认的构造函数。构造函数可以重载。

构造代码块:用于给所有的对象进行统一初始化,它在构造函数之前运行。

this关键字:代表的是调用this所在函数的那个对象,类内部函数之间的调用都是通过对象来完成的,只是默认省略了this。通过this就可以将成员变量和局部变量区分起来。

什么时候用this?当定义类的功能时,如果功能内部需要使用调用这个功能的对象,那么就用this代表这个对象。

this语句:用于构造函数之间的调用,并且只能放在构造函数的第一行(初始化动作要先执行),注意不要用this语句构成构造函数间的死循环。this(name)

static关键字:是一个修饰符,用于修饰成员(成员变量和成员方法),当成员被类修饰后,就多了一个调用方式,除了可以被对象调用外,还可以被类名直接调用:

类名.静态成员

特有数据随着对象走,放在堆内存中;共享数据,用static修饰,放在方法区中。

static的特点:随着类的加载而加载(也就是说,静态会随着类的消失而消失,说明它的生命周期最长),优先于对象而存在(明确一点,静态变量先存在,对象后存在),被所有对象所共享,可以被类名直接调用。

实例变量和类变量(静态变量)的区别:

1.             存放位置不同,类变量随着类的加载而存在于方法区中,实例变量随着对象的建立而存在于堆内存中。

2.             生命周期:类变量生命周期最长,随着类的消失而消失;实例变量生命周期随着对象的消失而消失。

静态使用的注意事项:

1.      静态方法只能访问静态成员,但非静态方法既可以访问静态成员也可以方法非静态成员。

2.      静态方法中不可以定义thissuper关键字:因为静态优先于对象而存在,所以静态方法中不可以出现this

3.      主函数是静态的。

静态的利弊:

利处:对对象的共享数据进行单独空间的存储,节省空间,没有必要每一个对象中都存储一份);可以直接被类名调用。

弊端:生命周期过长。访问出现局限性。(静态虽好只能访问静态)。

方法区:也叫共享区,数据区,一个类加载后都会开辟该类的方法区,其中存储着方法和方法体(可分为静态部分和非静态部分),一个类的方法区的开辟先于对象堆内存空间的开辟。

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

 pubic---代表着该函数访问权限是最大的。

static---带着这主函数随着类的加载就已经存在了。

void---主函数没有返回值。

main---不是关键字,但是是一个特殊的单词,可以被jvm识别。

String []  args:主函数的参数,参数类型是一个字符串类型的数组,args可以换成任意符合java规则的标示符,该数组是通过(java 类名.java 字符串……)命令传入的。

主函数有一般静态成员的特点,可以被其他静态成员所调用,也可以被对象调用。

什么时候使用静态

从两方面(静态函数和静态变量)入手。

什么时候定义静态变量?

 当对象中出现共享数据时,该数据被静态所修饰;对象中的特有数据要定义成非静态,存在于堆内存中。

什么时候定义静态函数?

          当功能内部没有访问到非静态数据或对象的特有数据,那么该功能可以定义成静态的

静态函数的应用之一:工具类,多个类都有的共性功能,可以将其抽取出来,封装在一个工具类(同时将工具类的构造函数私有),以方便复用。

制作帮助文档:

使用

/**

注释内容

@author

@version

*/

 

 

/**

注释内容

@param  arr

@return

@since

@see

@throws

*/

 

注意:能被提取的注释必须是publicprotected

静态代码块

格式:

static

{

         静态代码块的执行语句

}

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

注意:如果仅仅建立类的引用,则静态代码块并不执行。只用用了类中内容才加载类,加载类时才执行静态代码块。

对象的初始化过程

对与Person p =new Person(“zhangsan”,20);这句话的执行过程如下

1.      因为new用到了Person.class,所以会先找到该类的字节码文件,并将之加载进内存中。

2.      执行静态代码块,如果有的话,对类进行初始化。

3.      在堆内存中开辟内存空间,分配地址值。

4.      在堆内存中建立对象特有的属性,并对属性进行默认初始化。

5.      对属性进行显式初始化。

6.      执行构造代码块进行对象初始化。

7.      执行与之对应的构造函数进行初始化

8.      将地址值赋给栈内存中的引用变量。

对象调用成员过程

静态成员之间的调用省略了“类名.”,非静态成员之间的调用则省略了this

 

单例设计模式

设计模式:最早存在于建筑领域,后引入计算机设计。GOF总结了23中设计模式。设计模式偏重思想,要结合实际,否则就会显得很空乏。模式的综合就形成了框架。设计模式是解决某一类问题最行之有效的方法。

单例设计模式:解决一个类在内存中只有一个对象这样的问题。例如,配置文件。

如何形成单例?1.构造函数全部私有,避免其他程序过多建立该类对象,禁止其他程序建立该类对象;2.在类中创建一个本类对象并静态私有3.提供对外访问该对象的静态方法

 

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

单例设计模式分为:饿汉式和懒汉式。

 

第二个特征:继承

继承的特点1.提高了代码的复用性;2.让类与类之间产生关系,有了这个关系,才有了多态的特性。

注意:千万不要为了获取其他类的功能,简化代码而继承;必须是类与类之间又关系才可以继承,即所属关系为 is a

Java语言中只支持单继承,不支持多继承。原因:因为多继承容易带来安全隐患,当多个父类中定义了相同功能,而功能内容不同时,子类对象不能确定要运行哪一个。但java保留了这种机制,并用另一种形式来体现:多实现

Java支持多层继承,也即一个继承体系。如何使用一个继承体系中的功能?要想使用体系,先查阅父类的描述,因为父类中定义的是该体系中的共性功能。通过了解共性功能,就可以指定该体系的基本功能,那么这个体现已经基本可以使用了。那么在具体调用时,要创建子类对象,为什么呢?一是因为父类有可能不能创建对象,二是创建子类对象可以使用更多的功能,包括基本的也包括子类特有的。简单来说就是:查阅父类功能,创建子类对象使用功能。

类与类之间的关系:除了继承,还有聚集(聚合和组合)关系。

聚集可以用has  a来表示,按其紧密程度,又可分为聚合和组合。

聚合:公司与员工之间的关系。

组合:人与心脏。

一个类的成员包括:变量、函数和构造函数。那么继承后子父类的成员有什么特点?

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

(内存图)

2.子父类中函数的特点:重写。当子类出现与父类一模一样的函数时,当子类对象调用该函数时,会运行子类函数的内容,如同父类的函数被覆盖一样,这种情况就是函数的另一个特性重写(覆盖)。

重写的注意事项:a.子类覆盖父类的方法,必须保证子类该方法的权限大于等于父类权限;

b.静态只能覆盖静态(一般不这样写)。

重载与重写的区别:重载只看函数的参数列表,重写则子父类方法要一模一样。

3.子父类构造函数的特点:在对子类对象进行初始化时,父类的构造函数也会运行,这是因为子类构造函数默认第一行有一条隐式的语句super();,super()会访问父类的空参构造函数。而且子类中所有的构造函数默认第一行都是super()。

为什么子类一定要访问父类中的构造函数?因为父类的数据子类可以直接读取,所以子类对象建立时,需要先查看父类是如何对这些数据进行初始化的,所以子类对象在初始化时,要先访问一下父类中的构造函数。如果要访问父类中指定的构造函数,可以通过手动定义super语句的方式来指定。

注意:super语句一定要定义在子类构造函数的第一行。

结论:子类所有的构造函数,默认都会访问父类的空参数的构造函数。因为子类每一个构造函数内的第一行都有一句隐式super();当父类中没有空参数的构造函数时,子类必须手动通过super语句形式来指定要访问父类中的构造函数。当然,子类的构造函数第一行也可以手动指定this语句来访问本类中的构造函数。子类中至少会有一个构造函数会访问父类中的构造函数。

final关键字

final----最终,是一个修饰符。特点是:1,可以修饰类,函数和变量;2,被final修饰的类不可以继承;3,被final修饰的方法不能被复写;4,被final修饰的变量是一个常量,只能被赋值一次,既可以修饰成员,又可以修饰局部变量(当描述事物时,一些数据的出现值是固定的,那么为了增强阅读性,都给这些值起个名字,方便于阅读,而这个值不需要改变,所以加上final修饰。作为常量,常量书写规范所有字母都大写,如果由多个单词组成,单词通过 _ 连接。比如定义圆周率);5,内部类定义在类的局部位置上时,只能访问被final修饰的局部变量。

抽象类

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

抽象类的特点:

1.      抽象方法一定出现在抽象类中。

2.      抽象方法和抽象类都必须被abstract关键字修饰。

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

4.      抽象类中的抽象方法要被使用,必须由子类复写所有的抽象方法后,建立子类对象调用。如果子类只是覆盖了部分抽象方法,那么给子类还是一个抽象类。

抽象类和一般类没有太大的不同,该如何描述事物还怎样描述,只不过该事物出现了一些看不懂的东西,这些不确定的部分,也是该事物的功能,需要明确出现,但是无法定义主体,就通过抽象方法来表示

 

抽象类比一般类多了个抽象函数,就是类中可以定义抽象方法。抽象类不可以实例化。

特殊:抽象类中可以不定义抽象方法,这样做仅仅是为了不让给类建立对象。

模板设计模式

在定义功能时,功能的一部分是确定的,但是有一部分是不确定的,而确定的部分又在使用不确定的部分,那么这时就将不确定的部分暴露出去,由该类的子类去实现。

  

接口:初期理解,可以认为是一个特殊的抽象类,当抽象类中的方法都是抽象的,那么该类可以通过接口的形式来表示。class用于定义类,interface用于定义接口。

接口定义时,格式特点:

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

2.      接口中的成员都有固定的修饰符。
常量:public static final
方法:public abstract

注意----接口中的方法都是public的。

接口不可以创建对象,因为有抽象方法。需要被子类实现(通过implements关键字),子类对接口中的抽象方法都覆盖后,子类才可以实例化;否则子类是一个抽象类。接口的成员变量都是常量,不可悲改变。

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

接口间可以有继承关系,并且支持接口多继承;但注意被继承的多个接口之间不能存在仅有返回值不同的同名函数。

接口的特点:

接口是对外暴露的规则。

接口是程序的功能扩展。

接口可以用来多实现。

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

接口与接口之间可以有多继承关系。

接口是体系之外的扩展功能,比如一个公务员开了一家商店,开店是接口,不是公务员必备的功能。是一种暴露的规则,开发时,可以将联系紧密的两个部分分割成两个模块,实现模块化开发,加快开发进度,减少耦合。

第三个特征:多态

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

1.多态的基本体现

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

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

2.多态的前提

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

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

3.多态的弊端

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

4.多态的好处

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

5.多态的应用

6.多态的出现在代码中的特点(多态使用的注意事项)

        在多态中非静态成员函数的特点:

       在编译时期:参阅引用型变量中是否有调用的方法,有则编译通过,没有则编译失败。

         在运行时期:参阅对象所属的类中是否有调用的放。

         简单总结就是:非静态成员函数在多态调用时,编译看左边,运行看右边。

         在多态中,成员变量的特点:

         无论编译和运行,都参考左边(引用型变量所属的类);

      在多态中,静态成员函数的特点:

     无论编译和运行,都参考左边。

      引用数据类型的类型提升,或者叫向上转型;强制类型转换,也叫向下转型,强制将父类的引用,转成子类的引用。

我们能操作的是父类引用指向子类对象时,该应用既可以被提升,也可以被强制转换,多态自始至终都是子类对象在做着变化。

Object:是所有对象的直接或者间接父类。它的equals方法其实用的就是多态。

内部类

内部类的访问规则:

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

之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类中的引用,格式:外部类名.this

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

访问格式:

         1.当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。可以直接建立内部类对象。

格式:

         外部类名.内部类名变量名 =外部类对象.内部类对象;

         Outer.Inner in = newOuter().new Inner();

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

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

           static:内部类就局部static的属性。

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

        3.当内部类定义在局部时,不可以被成员修饰符修饰,可以直接访问外部类中的成员,因为还持有外部类中的引用,但是不可以访问所在局部中的变量,只能访问被final修饰的局部变量。

       4.匿名内部类

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


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值