Java面向对象(OOP)

来源:互联网 发布:jsonrpc4j javascript 编辑:程序博客网 时间:2024/06/05 00:25


  面向对象可以说是建立在面向过程之上的。比如说完成一项任务,从开始去做到完成结束是个过程,中间的步骤是面向过程。而又可以把 整个过程分成一个个小的过程并封装起来,就成为了一个个的方法(一个个小小的过程也就是方法体里面的功能执行),分别放到各自的类中,,用通过类声明并创建对象,该环节就是面向对象的过程,而方法执行的过程,也就是实现他的功能,我觉着还是面向过程。所以Java中:JVM底层是用c和c++实现的。

java类库就是用java语言实现的
1.   类是一种抽象的概念,是对同一类事物的抽象描述,任何事物都可以抽象成类(如汽车可以抽象成一个汽车类,其具有的属性也就是成员变量有车门,发动机,方向盘,座位,轮子。。。。),对象是类的一种具体表示形式,是具体的概念。先有类,然后由类来生成对象(Object)。对象又叫做实例(Instance)。
类又分为系统类(如API里面的,API里面的类的方法大部分都是静态方法,所以可以通过类名加方法名调用,lang包下的无需导入,其他包均需要导入)和自定义类。

      在这里就在说一下对象,每个类本身都有一个默认的构造方法(构造方法,方法名与类名一致,无返回值,当你不定义构造方法时,Java会自己带一个构造方法,默认的构造方法无参数,,当然你也可以自己定义带参数的构造方法,默认的构造方法不会显示出来),当你new一个对象时,Java会自动调用本身的不带参数的构造方法将该对象实例化,当你new一个对象时,如果带有参数,Java运行时就会调用你定义的与你传递的参数的类型一致的构造方法。建议:当你在定义一个带参构造方法时,一般会补充一个无参的构造方法以备后期使用。


2.类由两大部分构成:属性(成员变量)以及方法(方法里面的属性又叫做局部变量,作用域是在方法体内);成员变量 是有初始值的,在不赋初值的情况下默认为零,局部变量必须赋初值。属性一般用名词来表示,方法一般用动词来表示。类中,静态方法的调用可以通过:类名.方法名调用,也可以用创建对象,通过引用调用方法。非 静态方法只能通过创建对象调用。同一类和不同类中方法的调用都是这样。关于栈和堆:栈中存的是局部变量和引用,堆中存的是成员变量和对象,当new一个对象的时候,系统会在堆中分配空间给他,而该对象对应的类中的成员变量的值也会放到该内存空间中,该对象对应的引用变量也会获得该内存空间的地址值。

3.如果一个java源文件中定义了多个类,那么这些类中最多只能有一个类是public的,换句话说,定义的多个类只能有一个是public的。
4.在Java中进行方法的参数传递时,无论传递的是原生数据类型还是引用类型,参数传递方式统一是传值(pass by value)。Java中没有传引用(pass by reference)的概念。

   Java面向对象的三大特性:封装(Encapsulation),继承(Inheritance),多态(Polymorphism)。

  一:                                                                      封装

      封装就是包装的意思,用途就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被保护在抽象数据类型的内部,尽可能地隐藏内部的细节,只保留一些对外接口使之与外部发生联系。系统的其他对象只能通过包裹在数据外面的已经授权的操作来与这个封装的对象进行交流和交互。也就是说用户是无需知道对象内部的细节,但可以通过该对象对外的提供的接口来访问该对象。用通俗的语言来讲:一间房子里面的东西如家具,生活用品都是该房子的属性,房子里面还有各种各样的功能,而房子的四面墙就是将房子封装起来,把房子里面的信息隐藏起来,但我可以通过窗户和门来访问房子内部,查看内部的东西和使用里面的功能。

        对于封装而言,一个对象它所封装的是自己的属性和方法,所以它是不需要依赖其他对象就可以完成自己的操作。封装可以说贯穿于整个Java项目。正是因为封装,在开发项目的时候我们可以把整个项目模块化,就是分成各个模块,把每个模块分配给每个程序员去实现各自的功能,同时一起开发,大大节省了开发项目的时间和成本。

使用封装有四大好处:

           1、良好的封装能够减少耦合。 

           2、类内部的结构可以自由修改。

           3、可以对成员进行更精确的控制。    

           4、隐藏信息,实现细节。

       上面说到耦合我就在解释一下Java的耦合。

       对于Java来说,我们一直追求着,高内聚,低耦合。对于低耦合,我粗浅的理解是:一个完整的系统,模块与模块之间,尽可能的使其独立存在。也就是说,让每个模块,尽可能的独立完成某个特定的子功能。模块与模块之间的接口,尽量的少而简单。如果某两个模块间的关系比较复杂的话,最好首先考虑进一步的模块划分。这样有利于修改和组合。对于高内聚,我粗浅的理解是:在一个模块内,让每个元素之间都尽可能的紧密相连。也就是充分利用每一个元素的功能,各施所能,以最终实现某个功能。用面向对象的思想去考虑一个类的封装。一个方法,如何封装,拿到现实生活中来看,看这种能力(方法)是否是属于这类事物(类)的本能。如果是,就封装在这个类里。如果不是,则考虑封装在其它类里。如果这种能力,很多事物都具有,则一定要封装在这类事物的总类里。如果这种能力,很多事物都会经常用到,则可以封装成一个总类的静态方法。

 二:                                                                       继承


     在讲继承之前我们先说一下一个知识点,叫方法 的重载和重写。

     重载:(Overload)。表示两个或多个方法名字相同,但方法参数不同。方法参数不同有两层含义:1)参数个数不同。2)参数类型不同。 注意:方法的返回值对重载没有任何影响。

    重写:(Override):又叫做覆写,子类与父类的方法返回类型一样、方法名称一样,参数一样,这样我们说子类与父类的方法构成了重写关系。对重写的方法,子类的访问权限 修饰符级别大于父类的。例如父类的方法访问权限修饰符是default, 子类重写后的方法访问权限修饰符可以使用 protected    puclic

     再补充一下重载和重写的区别:重载发生在同一个类内部的两个或多个方法。重写发生在父类与子类之间。

             继承的概念:继承是is-a关系。Java是单继承的,意味着一个类只能从另一个类继承(被继承的类叫做父类【基类,base class】, 继承的类叫做子类),Java中的继承使用extends关键字。
              当生成子类对象时,Java默认首先调用父类的不带参数的构造方法,然后执行该构造方法,生成父类的对象。接下来,再去调用子类的构造方法,生成子类的对象。【要想生成子类的对象,首先需要生成父类的对象,没有父类对象就没有子类对象。比如说:没有父亲,就没有孩子】。在定义一个类的时候,如果没有显式指定该类的父类,那么该类就会继承于java.lang.Object类(JDK提供的一个类,Object类是Java中所有类的直接或间接父类)。

继承:

a)父类有的,子类也有

b)父类没有的,子类可以增加
c)父类有的,子类可以改变
d)构造方法不能被继承
e)方法和属性可以被继承
f)子类的构造方法隐式地调用父类的不带参数的构造方法
g)当父类没有不带参数的构造方法时,子类需要使用super来显式地调用父类的构造方法,super指的是对父类的引用
h)super关键字必须是构造方法中的第一行语句。

          Java类具有三种访问控制符:private、protected和public,同时当不写这三个访问控制符时,表现为一种默认的访问控制状态。因此,一共具有四种访问控制级别。  具体访问控制表现如下:

       private修饰的属性或方法为该类所特有,在任何其他类中都不能直接访问;  default修饰的属性或方法具有包访问特性,同一个包中的其他类可以访问;  protected修饰的属性或方法在同一个中的其他类可以访问,同时对于不在同一个包中的子类中也可以访问;  public修饰的属性或方法外部类中都可以直接访问。 

        当子类继承父类,子类可以继承父类中具有访问控制权限的属性和方法(一般来说是非private修饰的),对于private修饰的父类所特有的属性和方法,子类是继承不过来的。  当子类需要改变继承过来的方法时,也就是常说的重写父类的方法。一旦重写后,父类的此方法对子类来说表现为隐藏。以后子类的对象调用此方法时,都是调用子类重写后  的方法,但子类对象中想调用父类原来的此方法时,可以通过如下两种方式:

  1.将子类对象类型强制转化为父类类型,进行调用;  2.通过super调用。  同样的,如果在子类中定义父类中相同名称的属性时,父类属性在子类中表现为隐藏。   

this表示对当前对象的引用,在一个类中使用。具体用法:  

      1.当具多个重载的构造器时,且一个构造器需要调用另外一个构造器,在其第一行使用this(param)形式调用,且只能在第一行;

       2.当对象中一个方法需要调用本对象中其他方法时,使用this作为主调,也可以不写,实际上默认就是this作为主调;

        3.当对象属性和方法中的局部变量名称相同时,在该方法中需要显式的使用this作为主调,以表示对象的属性,若不存在此问题,可以不显式的写this。  其实,其牵涉到的一个问题就是变量的查找规则:先局部变量 => 当前类中定义的变量 => 其父类中定义的可以被子类继承的变量 => 父类...  

super是在子类和父类之间使用。具体用法:

        1. 当父类没有不带参数的构造方法时,子类需要使用super来显式地调用父类的构造方法,super指的是对父类的引用
,super关键字必须是构造方法中的第一行语句。

         2.当两个方法形成重写关系时,可以在子类方法中通过super.method()形式调用父类的method()方法,其中super.method()不必放在第一行语句,因此此时父类对象已经构造完毕,先调用父类的method()方法还是先调用子类的method()方法是根据程序的逻辑决定的。

总结:

this()和super()为构造方法,作用是在JVM堆中构建出一个对象。因此避免多次创建对象,同一个方法内只能调用一次this()或super()。同时为了避免操作对象时对象还未构建成功,需要this()和super()的调用在第一行实现【以此来创建对象】,防止异常.在普通的成员方法中,如果调用super()或者this(),你是想要重新创建一个对象吗?抱歉Java为了保证自身对象的合理性,不允许你做这样的操作。

三:                                                                 多态


          所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。 

           举个例子:我们可以把饮料看做成一个父类,而  雪碧  可乐  橙汁  都可以分别作为饮料的一个子类,我们new一个对象 :饮料 a =new 可乐();创建了一个饮料类型 的引用变量,该引用变量实际上是指向可乐类的对象。再比如  饮料 b =new 橙汁();我们可以使用父类创建不同的引用来指向不同的子类  这就是多态——我们只有在运行的时候才会知道引用变量所指向的具体实例对象。

                实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。 

               多态的作用:消除类型之间的耦合关系。 

               现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。

              Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。

               下面是多态存在的三个必要条件:   一、要有继承; 二、要有重写; 三、父类引用指向子类对象,也就是向上转型。            

               上面谈到继承时我们说过,子类继承父类所有的方法和属性(除构造方法,私有方法和私有属性)父类类型的引用可以调用父类中定义的所有属性和方法,而对于子类中定义而父类中没有的方法,它是无可奈何的;  对于父类中定义的方法,如果子类中重写了该方法,那么父类类型的引用将会调用子类中的这个方法,这就是动态连接。也可以叫做动态绑定。换个方式说,当父类型的引用指向子类型的对象时,此时的子类可以看做成父类,而此时子类本身特有的方法和属性是隐藏的。

原创粉丝点击