当前位置:网站首页 > Java基础 > 正文

java基础和c 区别



面向对象的思想

面向对象的主要思想是提供了类与对象的概念。类是对象的抽象,也可以说类是对象一种描述。对象是类的实例。高级编程语言通过面向对象思想让程序更符合人对真实世界的认识,让程序更容易让人理解并且更容易描述事物。

面向对象三大特性

面向对象的三大特性:。封装可以屏蔽对象的属性和实现细节,让程序员更关注业务本身的逻辑,java基础和c 区别进而更容易的开发出大型的软件。继承可避免重复的造轮子,并不是什么工作都从头开始做。也让描述变得简单,例如猫与白猫,把白猫描述成一种白色的猫,而不是一种白色的有四只腿、两个眼睛、一张嘴...的动物。也更符合人们的日常表达。多态主要是提供行为可变的一种能力。也就是接口(方法)的不同实现。多态分为编译时多态和运行时多态。编译时多态就是 Overload机制,通过函数签名(函数名,函数参数类型、个数、顺序相同,才表示签名相同)确定其唯一性,让同名称的函数有了多种形态。运行时多态就是Override机制,子类能重写父类的方法。运行时决定调用哪个方法,这样就可以让运行时方法有不同的实现。让子类进化父类的能力。

继承是子女的诉求,通过继承积累资产与能力,节省工作量。多态是父辈的期望。特别是没有实现的抽象方法,是要求子女去实现的,向外提供一种未来的能力。人生也是这样,想从父辈那里继承更多的资产,就是会受到更严格的约束。

java与c++三大特性的比较

封装性

  • c++是站在c语言角度设计的面向对象语言,class也是从struct演变来的,struct默认的访问权限是public的,而class默认的访问权限是private的,它们都支持程序员设置有不同的访问权限:private、protected、public。这个设计思想是封装数据,隐藏细节,但是c++又提供了friend函数,友元可以访问类的任何成员,破坏了封装。也就是说它的设计思想是封装,但是又提供了破坏这一思想的接口,这就出现了矛盾。友元是不能被继承和传递的,也就是父亲的朋友不是我的朋友,朋友的朋友也和我没有关系。如果想让他们与我是friend,必须申明。但是现实生活中,人际关系多多少少都会有点圈子文化。封装就是为隐藏细节,这种友元全是细节。所以java设计丢弃了friend。
  • c++是面向对象早期的发明的高级语言,其数据成员的思想设计是来自于人对真实世界的认知。现实生活中,类作为对象一种描述,其数据成员是对对象才有意义,所以在类中,对数据成员赋初值是没有意义的,故不支持类对数据成员赋初值。(主要的原因是.h文件引用,需要区分申明和定义的语义)对非静态数据成员赋初值,会出现如下情况:
 

也就是说,只有c++11才支持类给非静态数据成员赋一个默认值。否则会给出一个警告。

对静态数据成员赋初值,只要修改成会出现编译错误:

 

当然修改成是可以编译过的.对于编译器来说,只有const static的数据成员才会被识别为常量。

java没有以上限制,给数据成员赋默认值,主要是为了方便定制一个默认对象,申明一个类,直接new就可以得到一个默认对象,这个默认对象默认属性是可以在申明类的时候定制的。而不像c++,只能让编译器给类赋一个默认值,如果编译器调用自己添加的构造函数,一般为0, 如果程序员自己定义了构造函数,值不确定,如下:

 

对属于类的静态数据成员,java也是可以直接赋初值的,这是因为java类需要被classloader加载才能在jvm上运行,它的静态数据成员在被加载的那一时刻正好可以确定作用域。

  • const可以作用于类成员,包括数据成员和成员函数。表示不变的意思。但对const成员初始化和用法,规定比较多。
    1. const的非静态数据成员只能在初始化列表中初始化,.
    2. 如果申明一个const对象,只能调用对象的const方法。都是子女差别有点大.
    3. 如果一个函数签名一样,再申明一个同签名的const函数,居然能编译过。根据重载(overload)语义,这不是重载啊。。c++就当它是overload了。

个人感觉C++ const就是为兼容C的const,强制定义类与对象的const属性。所以java没有再使用const表示不变的意思,而是使用final,最终的。最终的类不能被继承,最终的方法不能被复写,最终的变量不能被修改。总之就是一个意思,最终的就是不可被改写

继承性

对于继承,c++是支持多继承的,非常强大,但是容易出现函数的二义性,这是不允许的。其实客观世界也就是两种繁殖方式:无性繁殖和有性繁殖。无性繁殖是产生的后代只有一个亲体,也就是后代只有一个parent。有性繁殖也只不过两个。c++这种多继承并不是只有两个,这个设计并不符合客观现实。如果一个人有多个父母,关系除了复杂,就是乱。如果处理不好会让代码耦合性更大,逻辑更复杂,关系更紊乱。并且会出现单个类设计和逻辑都是正常的,放在一起派生的子类就产生了二义性。java设计放弃了多重继承,采用无性繁殖的模式,一个顶层祖先Object类,派生类通过tree的模型关联在一起,因为类的parent只有一个,提供 了super指针,可以通过它回溯找到所有的祖先。并通过接口实现类的额外功能,可以理解为无性繁殖的基因突变。extends 、implements并不会引起歧义。
无论是c++,还是java,子类都可以继承父类的能力。只不过c++的多重继承,有可能产生二义性,也就是一个能力父母都有,子女不知道用哪个,尽量少使用多继承,获取能力一时爽,但有二义性时决策却很痛苦。是不要爸爸的,还是不要妈妈的,对孩子来说本身就是一个痛苦的选择。还有就是c++的const对象只能调用const方法。

多态性

说到多态,对于编译时多态,java和c++一样。但是运行时多态,java不需要virtual函数支持,子类可以Override父类成员方法。更符合实际情况,如果子类和父类的成员方法相同,对于程序设计来说,目的就是为Override。如果目的不是Override,干什么要写一个相同的成员方法呢?c++这种通过virtual关键字,就不方便了,在基类设计的时候,就要指定需要override的方法。这虽然可以支持运行时多态,但是支持多态的接口是一定的,显然限定了运行时多态的扩展性。例如:如果派生类需要Override基类的接口,如果基类中的此接口没有申明为virtual,还要修改基类的接口变成virtual,如果想修改成pure virtual接口,同时继承此基类的其它的实例类还要实现此接口。

  • 子类能隐藏父类同名普通成员,包括数据成员和成员函数。这个是隐藏不是重写。这个概念来自于C的变量作用域。内部作用域的变量隐藏外部作用域的同名变量。不是同名的普通成员,子类可以继承,这个继承是打引号的,本质上是子类能访问父类作用域内可以访问的成员。也就是说父类的作用域大于子类。C++的父子类的同签名成员函数为什么也要遵守C的变量作用域规则?我个人认为这是个设计缺陷,既然子类定义了同签名函数隐含的意思就是要重写,如果不重写,干嘛要定义一个同签名的函数。所以java优化这个设计,同名数据成员,子类隐藏父类的,同签名函数,子类重写父类的。
  • 把子类对象赋值给父类指针。在C++中,把一个子类实例赋值给父类指针,然后调用一个普通成员函数,调用的是父类的成员函数,如果父类没有实现这个成员函数,则报错。
  • 动态多态性,需要把成员函数申请成virtual,并且使用compound type(reference、pointer)的对象调用,才能实现运行时多态。也是就是说c++提供了oop的能力,但是还兼容c的面向过程。但是在设计程序时,正常会优先使用一种思想,好的代码,除了正常完成业务逻辑,方便阅读和维护更重要。

版权声明


相关文章:

  • java基础软件研发2025-04-24 21:34:03
  • java 基础详解 pdf2025-04-24 21:34:03
  • java基础3752025-04-24 21:34:03
  • java基础成品2025-04-24 21:34:03
  • java基础必写的项目2025-04-24 21:34:03
  • java语言程序设计基础篇 编程题2025-04-24 21:34:03
  • 有c语音基础学java2025-04-24 21:34:03
  • java切换基础位置2025-04-24 21:34:03
  • java基础等级考试2025-04-24 21:34:03
  • java程序基础书籍2025-04-24 21:34:03