面向对象技术中的对象就是现实世界中某个具体的实体在计算机逻辑中的映射和体现,而类则是同种对象的集合与抽象。C++和Java是当今两种主流的面向对象语言,所有的Java程序都是由类或者说是类的定义组成的。在我们的学习过程中应该自始至终地牢记这一点,因为这意味着Java是一种完全的面向对象语言。Java中的所有东西都必须置入一个类。不存在全局函数、全局数据,也没有像结构、枚举或者联合这种东西,一切只有“类”!
然而C++则不同,比如C++的main方法是置于所有的类之外的,除此之外还可以在类外定义其它的函数。在C++中,全局变量、结构、枚举、联合等一些列源于C的概念仍然存在。对于在这个问题上的区别,不同的人会有不同的看法,C++的优点是灵活机动,而且比较利于C程序员接受,因为在C中成立的事情在C++中基本上不会出现差错,他们只需要了解C++多了哪些东西便可以了,然而也正因为如此,C++杂糅了面向对象和面向过程的双重概念,由此产生出的很多机制在强化某部分功能的同时破坏了程序的整体结构。
与此相比,Java语言去除了C++中为了兼容C语言而保留的非面向对象的内容,对于对C比较习惯的人来说不是十分友好,在很多问题的处理上也显得有些弃简就繁,但是它以此换来了严谨和可靠的结构,以及在维护和管理上的方便。
1. 接口和抽象类:
Java通过interface关键字来表示接口,接口中不能包含非静态域字段,所有的域成员均是公有的抽象方法,如Comparable接口,如果希望利用Arrays.sort方法,数组的成员必须实现该接口。抽象类中包含抽象方法,和接口一样抽象类也不能被实例化。
1) 接口不能被实例化,但是可以声明接口的变量指向其实现类的对象。
2) 每个类只能有一个超类,但是可以实现多个接口。
以下为Java的接口和抽象类的定义方式:
public interface Comparable
{
int compareTo(Object other);
}
public interface Comparable<T>
{
int compareTo(T other);
}
abstract class Employee implements Comparable
{
public abstract int compareTo(Object other);
}
在C++中同样存在接口和抽象类的概念,也和Java一样不能被实例化,但是并没有相应的关键字存在,而是以一种潜在规则的方式存在,见如下代码:
//Comparable对象声明的方法中只有纯虚方法存在(析构函数除外),且没有任何成员变量。
class Comparable
{
public:
virtual ~Comparable() {}
//compareTo为纯虚方法
virtual int compareTo(Comparable& other) = 0;
}
//Employee对象中存在部分纯虚方法,且可以有成员变量存在。
class Employee
{
public:
virtual int compareTo(Comparable& other) { return 0; }
virtual int backgroud() = 0;
private:
int _age;
}
C++支持多重继承,JAVA每个类只能有一个超类,但是可以实现多个接口。
2、继承
C++中的继承:
#include<iostream>
using namespace std;
class A
{
public:
void test()
{
cout<<"I'm A\n ";
}
};
class B:public A
{
void test()
{
cout<<"I'm B\n'";
}
};
int main()
{
A* p = new B;
p->test();
return 0;
}
输出结果:
I'm A
也就是说如果子类的函数如果覆盖了基类的函数的话,如果实例化一个子类并且赋值给基类指针或者基类引用的话,调用被覆盖的函数其实是调用的是基类的成员函数。
JAVA中的继承:
public class A
{
public void testFun() {
System.out.print("I'm A");
}
}
public class B extends A
{
public void testFun() {
System.out.print("I'm B");
}
}
public class test {
public static void main(String[] args) {
// TODO Auto-generated method stub
A a = new B();
a.testFun();
//System.out.print("test");
}
}
结果输出:
I'm B
可以看到,对于Java来说,调用被覆盖的成员函数是通过基类的变量来调用子类的成员函数,这个和C++是不一样的。
这里之所以没有体现出C++的多态性,是因为没有virtual关键字。
3、对象的回收
在C++中,对象的释放和回收是通过编程人员执行某种特殊的操作来实现的,像利用new运算符创建对象一样,利用delete运算符可以回收对象。但在Java语言中,为方便、简化编程并减少错误,对象的回收是由系统的垃圾回收机制自动完成的。
Java的垃圾回收机制是一个系统后台线程,它与用户的程序共存,能够检测用户程序中各对象的状态。当它发现一个对象已经不能继续被程序利用时,就把这个对象记录下来,这种不能再使用的对象被称为内存垃圾。当垃圾达到一定数目且系统不是很忙时,垃圾回收线程会自动完成所有垃圾对象的内存释放工作,在这个过程中,在回收每个垃圾对象的同时,系统将自动调用执行它的终结器(finalize)方法。
finalize()方法与C++中的析构函数(Destructor)有类似的地方,但是finalize()是由垃圾收集器调用的,而且只负责释放“资源”(如打开的文件、套接字、端口、URL等等)。如需在一个特定的地点做某样事情,必须创建一个特殊的方法,并调用它,不能依赖finalize()。而在另一方面,C++中的所有对象都会(或者说“应该”)破坏,但并非Java中的所有对象都会被当作“垃圾”收集掉。由于Java不支持析构函数的概念,所以在必要的时候,必须谨慎地创建一个清除方法。而且针对类内的基础类以及成员对象,需要明确调用所有清除方法。