如今通常的语言都支持面向对象,而java更是将其作到很过度的地步,java是强制使用面向对象的写法,简单的写一个Hello Word都必须使用面向对象,这也是当初我很反感它的一点,固然如今也是很不喜欢它这一点。可是不得不说它设计的很优秀也很流行。
java
面向对象通常是将一些独立有类似功能的模块封装起来组成一个类,而后调用者没必要关注实现细节而只须要关注调用某个类方法便可。面向对象简化了程序设计。与之相对应的是面向过程,而C就是典型的面向过程的程序设计语言。c++
面向对象通常有3种特性:封装、继承、多态。此次主要讲述的是java中的封装型。数据库
在java中类的定义与C++中类的定义相似,只是在java中每定义一个方法或者成员变量都须要在前面添加一个访问的权限修饰符,好比下面的定义编程
class Student { private String name; private int age; public Student(){ } public Student(String name, int age){ this.name = name; this.age = age; } public int getAge(){ return this.age; } public String getName(){ return this.name; } public void setAge(int age){ this.age = age; } public void setName(String name){ this.name = name; } }
而C++中只须要将具备相同访问属性的放到一块,用一次修饰符便可。好比上面java代码对应的C++代码以下:安全
class Student { private: string name; int age; public: Student(){ } Student(string name, int age){ this->name = name; this->age = age; } int getAge(){ return this->age; } String getName(){ return this->name; } void setAge(int age){ this->age = age; } void setName(String name){ this->name = name; } }
在C++中类中的成员若是不给访问权限,默认是private, 而java中默认的访问权限是friendly,可是这个friendly在java中并非关键字,并且java中的public、private、protected 都必须明确指定,在java中这些关键字对应的访问权限以下:多线程
访问权限 | 当前类 | 同一个package | 子孙类 | 其余package |
---|---|---|---|---|
public | yes | yes | yes | yes |
protected | yes | yes | yes | no |
firendly | yes | yes | no | no |
private | yes | no | no | no |
从上一个表中能够看到public 对于类成员的访问彻底没有限制、而protected仅仅保护类成员不被其余包访问,默认的friendly只容许同一个包或者同一个类的成员访问,最后的private仅容许同一个类的成员访问,它们的访问权限是递增的,也就是public > protected > friendly > private编程语言
面向对象的封装性就体如今仅仅容许经过类方法访问类成员。这有助于保护类成员不被其余代码随意的篡改,并且若是类成员在进行修改时若是会涉及到其余变化,咱们只须要在get/set方法中控制便可,不须要外部使用人员了解这个细节。函数
假设如今有一个教务系统,里面须要存储学生的信息,那么若是不采用封装的方式而直接在类代码外进行访问的话,并且成员被访问的位置较多,一旦发现数据库中存储的数据发生错误,那么将没法肯定是在哪给定了错误的值,并且要对输入值进行判断的时候,每一个被访问的位置都要添加这些判断的代码,修改量较大,并且没法保证每一个位置都正常修改了。若是后续业务逻辑修改,那么这些工做又得从新作一遍。若是咱们将成员变量使用set和get方法进行封装,查看数据错误的问题只须要关注get/set方法,并且业务逻辑变动时只须要修改get/set方法。这点体现了封装性对数据的保护做用。this
在假设这里咱们采用多线程的方式来访问数据,那么为了保护数据,就须要添加相应的同步代码,若是直接访问,那么每当访问一次数据,就须要添加保护代码。这样就为使用人员添加了没必要要的麻烦,若是咱们将这些进行封装,而后告诉使用人员,这个类是线程安全的,那么使用人员直接调用而不用管其中的细节,后续若是咱们换一种同步的方式,也不影响其余人的使用。线程
C++中this关键字就是一个指针,经过eax寄存器传入到类的成员函数中,在成员函数中,经过this + 偏移地址来定位类中全部成员。而java中this除了能像c++中那样用于表示访问类成员外,还有另外两个做用
class Student { private String name; private int age; public Student(){ } public Student(String name){ this(); //调用无参构造 this.name = name; } public Student(String name, int age){ this(name); // 调用有一个参数的构造方法 this.age = age; } public int getAge(){ return this.age; } public String getName(){ return this.name; } public void setAge(int age){ this.age = age; } public void setName(String name){ this.name = name; } }
class Student { private String name; private int age; public Student(){ } public Student(String name){ this(); //调用无参构造 this.name = name; } public Student(String name, int age){ this(name); // 调用有一个参数的构造方法 this.age = age; } public int getAge(){ return this.age; } public String getName(){ return this.name; } public void setAge(int age){ this.age = age; } public void setName(String name){ this.name = name; } public boolean compare(Student stu){ return this == stu; //这里简单实用两者的地址进行比较 } }
java中的构造函数与C++中的相同。是在new对象的时候调用的函数。注意这里只是说它在new的时候调用的函数,并非在使用类的时候第一次调用的函数。
Java 中的构造方法必须与该类具备相同的名字,而且没有方法的返回类型。每一个类至少有一个构造方法。若是不写一个构造方法,Java 编程语言将提供一个默认的,该构造方法没有参数,并且方法体为空。若是一个类中已经定义了构造方法则系统再也不提供默认的构造方法。
java中不能直接访问内存,虽然它的类都是new出来的,可是资源的回收由垃圾回收机制来完成,那么它有析构函数吗?答案是确定的,java中也是有析构函数的。在C++中进行栈资源回收或者手工调用delete的时候才会进行析构函数的调用。而在java中,当垃圾回收器将要释放无用对象的内存时,先调用该对象的finalize()方法。这个finalize方法就是类的析构函数,这个方法是由Object这个基类提供的一个方法,Object子类能够选择重写它或者就用默认的。这个方法严格上应该是一个接口函数,与C++的析构并不相同。
Java 虚拟机的垃圾回收操做对程序彻底是透明的,所以程序没法预料某个无用对象的finalize()方法什么时候被调用。
上面说构造函数并非使用类时第一个调用的函数,第一个调用的函数应该是静态代码块(这个代码块应该不能被称之为函数)。静态代码块是第一次使用类的时候被调用,并且仅仅只调用这一次。它的定义以下:
class Student{ staic { System.out.println("调用静态代码块"); } }