C#和Java的类、继承、重写与多态
面向对象的三大特性是封装、继承、多态,C#和Java都是面向对象的语言所以他们的类、继承、重写与多态有很多共同点,但是实现上也存在一定的区别。其中Java中其实没有虚函数的概念,也可以认为Java的函数默认都是虚函数都可以被重写;而在C#中要用关键字virtual指明特定的函数为虚函数才可以实现重写。
多态
多态的意思的一个接口或对象的变量在运行时可以有多种不同的形态,这是通过运行时绑定(晚绑定)实现的。
一个接口或对象的变量在运行时可以动态地指向多个对象中的一个,所以多态的结果是直到运行的那一刻才知道具体执行的是哪个对象的方法。
通过继承接口实现多态
假如有一个接口A,A中有一个方法SayHi(),然后B和C实现了接口A,关系如下:
A <- B
A <- C
接口的多态:
- 声明一个接口A的变量:A a = null;
- 在运行的过程中动态地给a赋予B或C的对象
- 调用A的SayHi()方法,这时实现了动态地调用B或C的SayHi()
通过重写方法实现多态
重写指的是在继承的关系中,子类重写(override)了父类的相同签名的方法(相同方法名并且相同的参数)。
假如有一个类A,A中有一个虚函数(virtual)SayHi(),然后B和C继承了类A,并都重写了父类A的方法SayHi()关系如下:
A <- B
A <- C
重写的多态:
- 声明一个父类A的变量:A a = null;
- 在运行的过程中动态地给a赋予B或C的对象
- 调用a的SayHi()方法,这时实现了动态地调用B或C的SayHi()
C#中的重写
C#的重写必须使用关键字virtual和override,其中virtual用于父类的方法,指明该方法为虚函数,override用于子类的相应方法,指明该方法重写父类的方法。
class Program
{
static void Main(string[] args)
{
BaseClass obj = new DerivedClass();
obj.SayHi();
Console.ReadKey();
} class BaseClass
{
public virtual void SayHi()
{
Console.WriteLine("Hi Base.");
}
} class DerivedClass : BaseClass
{
public override void SayHi()
{
Console.WriteLine("Hi Derived.");
}
}
}
输出:
Hi Derived.
Java中的重写
java默认所有的方法都是虚函数(可以通过final关键字把方法声明为非虚函数),默认都可以被重写,所以java的重写要比C#简单一些:
public class Example {
public static void main(String[] args) {
BaseClass base = new DerivedClass();
base.SayHi();
}
} class BaseClass {
public void sayHi() {
System.out.println("Hi Base.");
}
} class DerivedClass extends BaseClass {
public void sayHi() {
System.out.println("Hi Derived.");
}
}
输出:
Hi Derived.
C#特有的new修饰符
C#的new修饰符的作用有点难以理解,官方定义是用于隐藏父类具有同签名的方法,隐藏是针对子类的,可以简单理解为:
声明一个和父类具有同样签名的方法并告诉编译器我这个方法和父类的方法没有任何联系。
单单从定义看很难理解它的真正含义,用代码来说话:
class Program
{
static void Main(string[] args)
{
BaseClass obj1 = new DerivedClass();
obj1.SayHi(); DerivedClass obj2 = new DerivedClass();
obj2.SayHi(); Console.ReadKey();
} class BaseClass
{
public void SayHi()
{
Console.WriteLine("Hi Base.");
}
} class DerivedClass : BaseClass
{
public new void SayHi()
{
Console.WriteLine("Hi Derived.");
}
}
}
输出:
Hi Base.
Hi Derived.
由运行结果可以看出来,obj1变量虽然在运行的过程中被赋予了DerivedClass对象,但是在调用SayHi()的时候实际是是调用了BaseClass的SayHi()。
结果分析:
- 因为new修饰的方法只是隐藏,SayHi()没有被重载,所以obj1的输出是:"Hi Base.",注意这是new修饰词的一个不好理解的坑。
- 在子类中用新的SayHi()隐藏了父类的SayHi(),所以obj2的输出是:"Hi Derived."
由此可见:
隐藏与多态无关
override和new的区别:
- override要和virtual配合使用,而new并不需要(new也可以隐藏非虚函数)
- 用virtual/override是为了实现多态,而new恰好相反
总结
从语法上看Java的重写与多态在实现上要比C#简洁一些,没有那么多的关键字,也没有那么多复杂难懂的语法。但是C#比Java多了一个特性就是子类可以拥有一个和父类具有同样签名的新方法,费那么多力气去换一个也不是太常用的特性是不是有点不值得呢。
转载请注明出处:http://www.cnblogs.com/keitsi/p/6137605.html
C#和Java的类、继承、重写与多态的更多相关文章
- java一个类 继承HttpServlet 和实现Servlet区别
java一个类 继承HttpServlet 和实现Servlet区别 servlet 是一个接口,如果实现这个接口,那么就必须实现接口里面定义的所有方法 而HttpServlet实现了servlet接 ...
- 【JAVA】类继承对父类静态变量的操作
对静态变量的操作存在继承时还是有一些模糊,做了个简单的测试: class Test { private String mName; public Test(String name) { setName ...
- Java的类继承
知识点1.继承作用:提高代码的重用性,继承之后子类可以继承父类中的属性和方法减少重复代码条件:子类和父类要满足is a的逻辑关系,才能使用继承.如:苹果 is a水果语法:使用extends 连接子类 ...
- java的类继承(与c++对比)
1. interface的引入 使用interface来定义某一类通用操作,而又不强制规定其实现,对于Java的流行真是太重要了. 以JDBC举例.在Java之前,C++与数据库建立连接,常用的一个技 ...
- java基础 类 & 继承
类 在Java中,类文件是以.java为后缀的代码文件,在每个类文件中可以有多个类,但是最多只允许出现一个public类,当有public类的时候,类文件的名称必须和public类的名称相同,若不存在 ...
- 为什么java实体类需要重写toString方法
如果没重写toString的情况: Object 类的 toString 方法 返回一个字符串,该字符串由类名(对象是该类的一个实例).at 标记符“@”和此对象哈希码的无符号十六进制表示组成.换句话 ...
- C++ 和 Java 对类继承的差异
#include <iostream> using namespace std; class Base { public: int i; Base() { i = ; fun(); } v ...
- Java: 类继承中 super关键字
super 关键字的作用有两个: 1)在子类中调用超类的构造器,完成实例域参数的初始化,调用构造器的语句只能作为另一个构造器(通常指的是子类构造器)的第一条语句出现, 2)在子类中调用超类的方法,如: ...
- Java面向对象之继承,方法重写,super关键字,员工类系列继承题
在程序中,如果想声明一个类继承另一个类,需要使用extends关键字. 格式: class 子类 extends 父类 {} 继承的好处 1.继承的出现提高了代码的复用性,提高软件开发效率. 2.继承 ...
随机推荐
- 【笔记】探索js 的this 对象 (第三部分)
了解完函数的调用区域是如何影响this 对象的,还有this 的各种绑定方式以及各种绑定方式的优先级后 最后一部分,来了解一下this 的一些例外情况 1.被忽略的this 例如在使用bind 方法时 ...
- 记一次vue2项目部署nginx静态文件404解决过程
github上下的一个vue2的项目,运行可以的,webpack打包后,nginx请求报错: 发现路径很奇怪啊,所以果断来到build.js文件中看看是不是哪里不对. 已经一番引用查找: 发现在这里配 ...
- java 获取进程的processId
package us.mine.demo.jvm.util; import java.lang.management.ManagementFactory; import java.lang.manag ...
- 用户手册是Yasm汇编
本文档的用户手册是Yasm汇编. 它是介绍和通用所有Yasm用户参考. 英文的参考:http://www.cnblogs.com/coryxie/p/3959888.html 1 .介绍 Yasm b ...
- 我的Android进阶之旅------>Android关于TextWatcher的初步了解
首先来看一下TextWatcher的源码 package android.text; /** * When an object of a type is attached to an Editable ...
- Codeforces Round #105 D. Bag of mice 概率dp
http://codeforces.com/contest/148/problem/D 题目意思是龙和公主轮流从袋子里抽老鼠.袋子里有白老师 W 仅仅.黑老师 D 仅仅.公主先抽,第一个抽出白老鼠的胜 ...
- 原来这是一个经典面试题-------Day61
前几天在table的操作中,记录了动态生成表格的三种方式: 1.html语言的拼接:用字符串或者数组拼接在html语言中,这个理解起来最直观 2.插入行和列:insertRow()和insertCel ...
- OTU_Network&calc_otu
# -*- coding: utf-8 -*- # __author__ = 'JieYap' from biocluster.agent import Agent from biocluster.t ...
- 《Javascript权威指南》学习笔记之十九--HTML5 DOM新标准---处理文档元信息和管理交互能力
一.了解DOM 1.DOM是Document Object Model的缩写,即文档对象类型,是文档在内存中的表示形式,是一个应用程序接口,定义了文档的逻辑结构以及一套訪问和处理文档的方法. 2.HT ...
- TimesTen 应用层数据库缓存学习:4. 仅仅读缓存
在运行本文样例前.首先先运行TimesTen 应用层数据库缓存学习:2. 环境准备中的操作. Read-only Cache Group的概念 仅仅读缓存组例如以下图: 仅仅读缓存组(Read-Onl ...