在Java中核心思想为OOP(object-oriented programming)即面向对象编程。
面向对象是指一种物以类聚,分类的思维模式,先总体思考需要哪些分类,即在宏观上进行把握。
对于所解决的问题,先从整体上分析,后对分类进行单独思考,针对某个分类下的细节,进行具体的微观思考,按照步骤一步步处理,即面向过程思考。
OOP的本质是以类的方式组织代码,以对象的方式封装的数据。
OOP的三大特性:封装、继承、多态,本文将会在之后一一讲解。
类是一种抽象的数据类型,它是对于某一类事物整体描述,但是不能代表某一个具体的事物。类中只包含两部分,一为属性,另一为方法。
在类中,静态的属性是指属性,动态的行为是指方法。
对象,指的是对抽象概念的具体实例。使用new关键字来创建对象,即对一个类进行实例化后会返回一个自己的对象,如下图所示。
注:对象在创建时,除了分配内存外,还会对创建好的对象进行默认的初始化以及对类中构造器的调用。
补充:
一个项目应该只存在一个main方法,故可以通过设置一个启动类Application类,来统筹项目的运行和测试,如下图所示。
使用this可以用来表示自身,必须放在非静态方法中才会起作用。通过this + "." + 属性 或this + "." + 方法来调用类中的属性和方法。this的四种用法,如下所示。
引用成员变量。在Java中采用的规定是当变量的作用范围重叠时,作用域小的变量会覆盖作用域大的变量。所以,当构造器和方法中的参数(局部变量)与类的成员变量相同时,局部变量起作用。故而,为了使成员变量起作用,需要采用this来对成员变量进行引用,如下图所示。
注:如果当构造器和方法中的参数(局部变量)与类的成员变量不相同,那么this可以省略,方法与构造器中可以直接调用成员变量,如下图所示。
代表当前自身类的对象,在一个类的构造方法内部,可以用this来代表自身类的对象,如下图所示。
在自身构造方法(构造器)内部引用其他构造方法。通过在不带参的构造方法内部,使用this(参数)调用了另外一个构造方法,其中,参数是其他构造方法所需要传递的参数值,如下图所示。
使用此方法,可以在一个类的内部构造方法较多时,只书写一个构造方法的内部功能代码,然后其他的构造方法都通过调用该构造方法来实现,这样即保证了所有的构造统一,又降低了代码重复。
注:在构造方法内部,使用this关键字调用其它的构造方法时,调用的代码只能出现在构造方法内部的第一行!!!在构造方法内部使用this关键字调用构造方法最多只出现一次!!!
引用成员方法。在一个类的内部,成员方法之间的互相调用可以使用this + "."+方法名来调用,通常this可以省略,如下图所示。
在创建一个新类的时候,即使在类中什么也不写,也会存在一个无参的构造方法(也叫构造器)。构造器具有两个特点:
必须和类的名字相同。
没有返回值类型,特别的:void类型也没有。
定义方式,如下式所示,其中上为无参构造器,下为有参构造器。
public class Person{ public Person(){ } public Person(Sting name, int age){ } }
注:若定义了有参构造,那么无参构造就必须要显示定义,这样才能接着用无参构造器。能够定义有参、无参多个构造器,本质上为方法的重载。
使用new关键字,本质上来说就是在调用构造器。使用构造器可以用来初始化对象的值。
注:创造构造器的快捷键为:Alt + insert 。在笔记本电脑上,使用Alt + Fn +insert,来实现构造器的创建,如下图所示。
封装的本质是实现追求高内聚、低耦合,高内聚是指类的内部数据操作、细节都由自己来完成,不允许有外部的干扰。低耦合是指仅暴露少量的方法给外部使用。
封装依赖于关键字private,如下式所示。
private String name;
在类中,私有的属性,不可以在main()方法中直接调用,如下图所示。
为了操作这些私有属性,Java中也提供了一些public的get()、set()方法。其中,get()方法用来获得属性,如下图所示。
set()方法用于给这个属性设置值,如下图所示。
注:使用Alt + insert快捷键可以自动生成get与set方法,如下图所示。
利用封装,可以实现一些安全性检查。例如:遇到不合法的输入,可以在set()方法中进行处理。
使用封装:
提高了程序的安全性,起到保护数据作用。
隐藏代码的实现细节。
统一接口,如set()方法、get()方法的统一。
提高系统的可维护性。
继承为类与类之间的一种关系,是对一批类的抽象。在Java中,只有单继承,没有多继承。
继承的关键词为:extends ,继承关系的实现,如下式所示。
public class Student extends Person{}
其中,Student类为子类,Person类为父类,子类继承父类,子类是父类的一种扩展。子类可以继承父类所有的public(公共)方法,也可以继承父类中的public(公共)属性,如下图所示。
注:
补充:属性前修饰符可分为public、protected、default、private几种,只有default和public能够用来修饰类,而变量和方法的修饰,四种修饰符都可以。其中,具体权限范围,如下表所示。
范围 | private | default | protected | public |
---|---|---|---|---|
同一包中的同一类 | √ | √ | √ | √ |
同一包中的不同类 | √ | √ | √ | |
不同包中的子类 | √ | √ | ||
不同包中的非子类 | √ |
使用super可以调用父类的属性和父类的方法,如下图所示。
注:
super调用父类的构造方法,只能在构造方法的第一个,一般来说,在子类中会隐藏调用父类构造器的代码,父类构造器显性显示,如下图所示。
同理,调用自己的构造器this(),也得在第一行。若有父类为有参构造,一般来说其前面需要加一个无参构造,否则子类无法直接super(),当然,直接在子类中调用父类中的有参构造也行,如下图所示。
super必须且只能出现在子类的方法或者构造方法中。
super和this 不能同时调用构造方法。
补充:super与this的不同,如下表所示。
对象 | 前提 | 构造方法 | |
---|---|---|---|
this | 本身的对象 | 无继承也可使用 | this()本类的构造 |
super | 父类对象的引用 | 只有在继承条件下才能使用 | super()父类构造 |
重写都是方法的重写,和属性没有关系。子类继承了父类才可以重写方法,方法的重写如下图所示。
注:
重写只发生在子、父类之间,重载发生在一个类中。
子类和父类的方法要保持一致,但方法体不同。
重写的方法都是非静态类型方法。
重写实现了子类对父类方法的"量体裁衣",子类可以选择自己满足、需要的方法。
补:可以使用快捷键alt + insert来重写父类中的方法,如下图所示。
当父类的引用指向子类时,如下式所示。
InheritExample1 inheritExample11 = new InheritExample2();
其中InheritExample1为父类,InheritExample2为子类。inheritExample11.test()所调用的方法为子类对父类方法的重写方法,如下图所示。
综上:方法的调用只和左边定义的数据类型有关,对象能执行那些方法主要看对象左边的类型,和右边的关系不大。如上图所示,定义了父类类型,但new了子类对象,故要实现父类中的方法需要在子类中重写父类中的方法。