C++ Concept 和Java 接口

Concept及接口

我会用Java写个case来解释什么是C++的Concept。Concept可以理解为接口,它是一种广义的接口。不同于Java的Interface,通俗地讲,Java的Interface匹配于C++的纯虚类,但Concept这种接口更广泛一些——任何符合该Concept要求的类型都属于该Concept.事实上,我认为Java也有能力实现Concept的.

我们姑且称Concept为广义的,Interface是狭义的,你会看到这么称呼是有道理的。

狭义的 Printer接口

C++版的Printer接口:

class Printer
{
public:
virtual void print() = 0;
virtual ~Printer() = 0;
};

Java版的Printer接口:

interface Printer{
public void print();
}

这时一定有人跳出来说,不对,它们不一样。

是的,它们(C++纯虚类和Java interface)略有不同,但C++纯虚类和 Java abstract class也不一样。事实上:

  • C++纯虚类对应于Java interface

    • 你必须手动声明C++纯虚类的虚析构函数,否则在delete指向派生类的基类指针时不能够析构基类,事实上,纯虚类的析构函数也被声明为纯虚函数,如果你只派生一次,你忘记声明析构函数为虚函数也没关系,因为纯虚析构函数啥也不干——但这不是个Best Practice,因为谁也不敢保证纯虚类只派生一次而没有被多层继承;Java没有析构函数的概念。这点是不同的。
    • C++纯虚类有构造函数,而Java interface没有构造函数。
    • C++纯虚类可以有成员变量(不推荐),而Java interface不可以有。
  • C++虚类对应于Java抽象类
    • 如上(虚)析构函数的区别。
    • C++可以多重继承,Java抽象类只能被单继承。

上述思想可以说是面向对象语言的基础,无论C++、Java还是C#、python,只要是面向对象编程范式的语言,他们都有 运行时多态 这种功能。

为何分道扬镳?

事实上,C++并没有纯虚类这个概念,只有一个abstract class的概念,它包含纯虚类。在此 定义C++的纯虚类为只包含纯虚函数的类(除去默认生成的构造函数)

如你所见,在面向对象设计的时候,两种语言选择了不同的路。Java晚于C++出现,它吸取了C++的设计经验,抽象出一个类似纯虚类的概念即接口,用以描述一组类似的功能实现。Java是基于如下考虑才做这种设计的:

Java通过提出接口的概念、规定只许单继承,规避多重继承的复杂。多重继承的复杂是 C++主流思想不选择设计 类似Java标准库的这种 面向对象编程范式的库的重要原因。我们知道C++是个多范式语言,目前的主流是使用基于模板编程的范式设计标准库。

设想一情形:A、B、C是三个提供不同功能的纯虚类(接口),而类ab实现了A、B的功能,类bc实现了B、C的功能,现在有需求说要设计一个具有A、B、C功能的类,你可以:

  • 1、选择abc继承自ab、bc,重现实现B
  • 2、选择abc实现A、B、C接口

我不敢说哪一种是对错,无疑第二种方法更清晰明了,虽然要啰嗦一些。而如果你用的Java,你没有第一种方式可以选择。——当然,实际工作中你遇到的情形不可能这么傻,实际情况要复杂得多:ab和bc的B功能实现很可能不一样,而abc需要的B功能实现可能是ab或bc中的一种、或者完全是另一种B的实现,因此从软件工程的角度来说,你必须选择第二种实现。

广义的 Printer Concept

我们定义一种Printer Concept,所有具有如下要求的类型都属于该Concept:

  • 具有参数为空的 default constructor。
  • 具有一个参数为空的print成员函数(方法).

下面二者最重要的区别: C++ Concept把错误提前到了编译期,而Java版的Concept错误在运行期。

C++版Printer Concept:

C++的Concept是基于模板范式的 编译期多态 .

#include <iostream>
#include <cstdlib> class ChinesePrinter
{
public:
void print()
{
std::cout << "你好\n";
}
}; class EnglishPrinter
{
public:
void print()
{
std::cout << "hello\n";
}
}; template <typename Printer>
class PrinterUser
{
public:
void action ( Printer p )
{
p.print();
}
void action()
{
Printer p{};
p.print();
}
}; int main()
{
{
ChinesePrinter cp{};
PrinterUser<ChinesePrinter> cpu{};
cpu.action ();
}
{
EnglishPrinter cp{};
PrinterUser<EnglishPrinter> epu{};
epu.action ();
}
system("pause");
}

Java版Printer Concept:

虽然我们可以通过实现InvocationHandler接口得到一个更通用的Concept,但无论如何这都是一个玩具。我们先不论这个Concept对于Java有什么意义,但无疑Concept的提出对于C++是十分重要的。

package org.go;

import java.lang.reflect.Method;

public class PrinterUser {
Class Printer_ = null;
public PrinterUser(Class Printer) {
Printer_ = Printer;
} public static void main(String[] args) {
{
PrinterUser cpu = new PrinterUser(ChinesePrinter.class);
cpu.action();
}
{
PrinterUser epu = new PrinterUser(EnglishPrinter.class);
epu.action();
}
} public void action() {
Concept c = new Concept("print");
c.call(Printer_);
}
} class ChinesePrinter {
public void print() {
System.out.println("你好");
}
} class EnglishPrinter {
public void print() {
System.out.println("hello");
}
} class Concept {
private String conceptName_; public Concept(String conceptName) {
conceptName_ = conceptName;
} public void call(Object printConcept) {
try {
Method printMethod = printConcept.getClass().getMethod(conceptName_, null);
printMethod.invoke(printConcept, null);
} catch (Exception e) {
e.printStackTrace();
}
} public void call(Class clz) {
try {
Method printMethod = clz.getMethod(conceptName_, null);
printMethod.invoke(clz.newInstance(), null);
} catch (Exception e) {
e.printStackTrace();
}
}
}

狭义的 接口实现 与广义的Concept对比

假如我们还有这样一个接口:

C++:

class Screen
{
public:
virtual void print() = 0;
virtual ~Screen() = 0;
};

Java:

interface Screen{
public void print();
}

无论是Java还是C++,上述的Screen和Printer接口(纯虚类) 都符合 我们提出的Printer Concept。Concept是更高的一层抽象。是的没有错:类型是一类数据结构的抽象,接口是类型的抽象,Concept是接口的抽象。由此可见,interface对Java有多重要,Concept对C++就有多重要——或者说,接口对于编程有多么重要,Concept对C++就有多重要。

C++ Concept 和Java 接口的更多相关文章

  1. java接口调用——webservice就是一个RPC而已

    很多新手一听到接口就蒙逼,不知道接口是什么!其实接口就是RPC,通过远程访问别的程序提供的方法,然后获得该方法执行的接口,而不需要在本地执行该方法.就是本地方法调用的升级版而已,我明天会上一篇如何通过 ...

  2. java 接口的作用和好处

    1.java 接口的作用 http://blog.csdn.net/hack_bug/article/details/7634737 2.一位Java大牛的回答 很多JAVA初级程序员对于接口存在的意 ...

  3. java接口

    一.定义 Java接口(Interface),是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为( ...

  4. java接口的嵌套

    java接口 1.接口中定义的变量默认是public static final 型,且必须给其初值,所以实现类中不能重新定义,也不能改变其值 2.接口中的方法默认都是 public abstract ...

  5. java 接口和抽象类的区别

    java 接口和抽象类的区别抽象类:1.含有抽象方法的类一定为抽象类,反过来抽象类,不一定含有抽象方法:2.抽象类必须用abstract来进行定义,抽象方法也必须用abstract来进行定义:3.抽象 ...

  6. java 接口(上)

    1.接口中的方法都是抽象方法.而普通的抽象类里面不一定都是抽象方法.抽象类中必须有抽象方法,同时也可以有非抽象方法.继承抽象父类的子类中,如果依然有抽象方法,那么这个子类也是抽象类.即只要类中有抽象方 ...

  7. java接口和抽象类

    关于接口 1.创建一个接口,需要使用interface关键字. 2.实现一个接口,需要使用implements关键字. 3.接口的成员属性都是静态常量(默认public static final). ...

  8. python面向对象进阶 反射 单例模式 以及python实现类似java接口功能

    本篇将详细介绍Python 类的成员.成员修饰符.类的特殊成员. 类的成员 类的成员可以分为三大类:字段.方法和特性. 注:所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存 ...

  9. 初探设计:Java接口和抽象类何时用?怎么用?

    今天犯了个错: “接口变动,伤筋动骨,除非你确定只有你一个人在用”.哪怕只是throw了一个新的Exception.哈哈,这是我犯的错误. 一.接口和抽象类 类,即一个对象. 先抽象类,就是抽象出类的 ...

随机推荐

  1. 浅析python 的import 模块(转)

    摘要: 学习python有几天了,对import一直不是很清楚,和C里面的include是否一样,重复引入有问题么?搜索路径是怎样的?整理解决下我的疑问. 一 模块的搜索路径 模块的搜索路径都放在了s ...

  2. HTML5 开发APP(MUI的一些特性)

    先附mui文档地址:http://dev.dcloud.net.cn/mui/ui/  .mui的UI组件比较简单而且在文档中很好找就不过多说了. 1 在app开发中,使用HTML5+的api,必须m ...

  3. Android 性能测试——Memory Monitor 工具

    Android 性能测试--Memory Monitor 工具 Memory Monitor能做什么? 实时查看App的内存分配情况 快速判断App是否由于GC操作造成卡顿 快速判断App的Crash ...

  4. 使用gitLab 或 github 关联本地仓库

    要先在git里面注册自己的邮箱 然后: git commit -m 是为本次提交命名 刷新gitLab 发现更新了

  5. 修改wampsever默认密码

    wamp初始默认mysql账号:root 密码: 空 准备修改为,账号:root 密码:xys829475 1.在phpMyAdmin界面中点击[用户],将用户概况中的所有用户名为[root]的用户的 ...

  6. 19. leetcode 100. Same Tree

    Given two binary trees, write a function to check if they are equal or not. Two binary trees are con ...

  7. HDU5734 Acperience(数学推导)

    Problem Description Deep neural networks (DNN) have shown significant improvements in several applic ...

  8. laravel框架cookie应用到中间件的理解

    昨天博主接到一个委托的需求,大数据同事想要在请求日志抓取数据,希望在我的每个页面进行cookie的种植,方便他们进行定位分析,我思考了一下,简单呀,首先考虑的是通过中间件进行cookie种植,但是随后 ...

  9. hdu--1077--Catching Fish

    思路:   1.枚举两点确定圆心,大于2不用考虑   2.逐个判断判断距圆心的距离小于1.00001符合题意 这个题,主要在求圆心上废了不少功夫,但是仍存在问题 #include<iostrea ...

  10. [原创] Python3.6+request+beautiful 半次元Top100 爬虫实战,将小姐姐的cos美图获得

    1 技术栈 Python3.6 Python的版本 request 得到网页html.jpg等资源的lib beautifulsoup 解析html的利器 html5lib 指定beautifulso ...