经常会有人问:小伙子,有没有对象啊,要不要大叔我帮你介绍一个啊,小伙子会说:大叔,不用我自己new一个就好了。(PS:活该你没有对象)

上边当然是一个段子咯,程序员那会没有对象,自己new一个就有了啊。好了进入今天的主题 new和this的关键字。

new关键字

new 关键字可用作运算符、修饰符或约束三种用法:

1) new 运算符:用于创建对象和调用构造函数。

a)   Person person = new Person();//new是一个运算符
(1)在内存中开辟一块合适大小的空间
(2)在这个空间里创建对象
(3)调用这个对象的构造函数
(4)返回这个空间的引用地址

代码展示:

class Program
{
static void Main(string[] args)
{
Reporter rep = new Reporter("记者", 11, '男', "偷拍");
rep.SayHello();
rep.Test();
Console.ReadKey();
}
} public class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
private char _gender;
public char Gender
{
get { return _gender; }
set { _gender = value; }
} public Person(string name, int age, char gender)
{
this.Name = name;
this.Age = age;
this.Gender = gender;
} public void Test()
{
Console.WriteLine("测试");
} public void SayHello()
{
Console.WriteLine("大家好,我是人类");
}
} public class Reporter : Person
{
public Reporter(string name, int age, char gender, string hobby)
: base(name, age, gender)
{
this.Hobby = hobby;
} private string _hobby; public string Hobby
{
get { return _hobby; }
set { _hobby = value; }
} public void ReporterSayHello()
{
Console.WriteLine("我叫{0},我是一名狗仔,我的爱好是{1},我是{2}生,我今年{3}岁了", this.Name, this.Hobby, this.Gender, this.Age);
} public new void SayHello()
{
Console.WriteLine("大家好,我是记者");
}
}

  

2) new 修饰符:在用作修饰符时,new 关键字可以显式隐藏从基类继承的成员。

代码展示:

public class BaseClass
{
public void functionA()
{
Console.WriteLine("BaseFunctionA http://www.cnblogs.com/sosoft/");
}
public virtual void functionB()
{
Console.WriteLine("BaseFunctionB http://www.cnblogs.com/sosoft/");
}
}
public class DerivedClass:BaseClass
{
public new void functionA()
{
Console.WriteLine("DerivedFunctionA http://www.cnblogs.com/sosoft/");
}
public override void functionB()
{
Console.WriteLine("DerivedFunctionB http://www.cnblogs.com/sosoft/");
}
} 调用:
BaseClass baseFunction=new DerivedClass();
baseFunction.functionA();
baseFunction.functionB();

运行结果:

 BaseFunctionA http://www.cnblogs.com/sosoft/

 DerivedFunctionB http://www.cnblogs.com/sosoft/

new是隐藏基类方法,override是覆写基类方法。如果要访问new隐藏了的基类成员需要使用base关键字实现。

隐藏和重写基类方法的异同:

1:方法重写:就是在基类中的方法用virtual关键字来标识,然后在继承类中对该类进行重写(override),这样基类中的方法已经被重写了,已经失去了功能了。当让基类的对象的引用直接指向继承类的对象时(多态性),调用该方法则是调用的继承类的方法。

2:方法隐藏:无论基类中的方法是否用了virtual关键字,继承类中都可以用new关键字(如果不用new的话,不会产生错误,但会生成一个编译警告)将基类中的方法隐藏,所谓隐藏就是隐藏,不像重写,重写就是原来的(基类中)已经不存在了,而隐藏是原来的还存在。所以当让基类的对象的引用直接指向继承类的对象时(多态性),调用该方法则是调用的基类的方法。

3new 约束:用于在泛型声明中约束可能用作类型参数的参数的类型。

代码展示:

class Person<T> where T : new()
{
public T GetName()
{
return new T();
}
} class Boy
{
private string _name; public string Name
{
get{return _name;}
set { _name = value; }
} public Boy()
{
_name = "feng";
}
} class Program
{
static void Main(string[] args)
{
Person<Boy> MBoy = new Person<Boy>(); Boy a = new Boy();
Console.WriteLine(a.Name); Console.WriteLine(MBoy.GetName().Name);
Console.ReadKey();
}
}

运行结果:

打印出2个"feng"

4) new 实现多态

a)  比如通过基类扩展来实现继承式多态.

b)  通过继承接口来实现多态.

代码展示:

class Num
{
public static int i = 111; public virtual void ShowClassInfo()
{
Console.WriteLine("我是基类呵呵");
}
public virtual void ShowNum()
{
Console.WriteLine("基类的数字是{0}", i.ToString());
}
} class SubNum : Num
{
new public static int i = 222; //new 作为修饰符:只是隐藏基类同名方法
public new virtual void ShowClassInfo()
{
Console.WriteLine("我是子类哈哈");
} //override则是覆写了基类的方法
public override void ShowNum()
{
Console.WriteLine("子类的数字是{0}", i.ToString());
}
} class Program
{
static void Main(string[] args)
{
Num num1 = new Num();//new 运算符用法
num1.ShowNum();
SubNum sbnum = new SubNum();
//下面2个调用的都是子类的方法 但是实现机制不一样
sbnum.ShowNum();//结果:222 sbnum.ShowClassInfo();//结果:我是子类哈哈 //new作为多态的用法:下面是典型的基类继承似多态
Num num2 = new SubNum();//num2虽然是基类的变量,但是指向了之类SubNum实例的引用 //调用方法时会在运行期检查虚拟方法表,来确定要调用的方法
num2.ShowClassInfo();//由于方法只是被隐藏了,没有被重写 所有还是调用的基类的方法 //结果:我是子类呵呵 num2.ShowNum();//方法被覆盖了 所有调用的是子类的方法 //结果: 222
Console.ReadKey();
}
}

注意:前方高能:

new关键字在我们的程序中可谓是无时不刻在用到,那么new关键字都可以用在哪些地方呢?考虑以下几个问题:
1、new一个class对象和new一个struct或者new一个enum有什么不同?
  答:new一个class时,new完成2个内容:一是调用newobj命令为实例在托管堆中分配内存,二是调用构造函数实现对象初始化。
  new一个struct时,new运算符用于调用其构造函数,完成实例的初始化。
2、new在.NET中除了创建对象实例外,还可以做什么?
  答:new关键字:作为运算符可以创建对象和调用构造函数;
  作为修饰符可以用于向基类成员隐藏继承成员,实现派生类中隐藏基类的virtual方法,不能和override共存;
  作为约束可以在泛型声明中约束可能用作类型参数的参数类型,即new约束指定泛型类声明中的任何类型参数都必须要有公共的无参构造函数;
  使用new关键字实现多态。
3、new运算符可以重载吗?
  答:new运算符不可以重载。
4、泛型中new关键字的作用?
  答:new运算符用于返回一个引用,指向系统分配的托管堆的内存地址,new分配内存失败,将引发OutOfMemoryException异常。
5、new一个继承下来的方法和override有什么区别?
  答:new是隐藏基类方法,override是覆写基类方法。如果要访问new隐藏了的基类成员需要使用base关键字实现。
6、int i和int i = new int()有什么不同?
  答:new一个int时,new运算符用于初始化其值为0,使构造函数完成更优越的初始化操作。

 

this关键字

1)、代表当前类的对象

代码展示:

class MyClass
{
// 声明一个名为"myVal"的整型字段
public int myVal = 10; // 声明一个构造函数,该函数带一个名为"myVal"的参数
public MyClass(int myVal)
{
// "this"表示MyClass类的当前实例
// 在这里通过this可以在语义上区分成员名myVal和参数名myVal
this.myVal += myVal; // 使用this作为当前对象的实参传递给Compute方法
int res = myVal + MyClass1.Compute(this);
}
}

  

2)、在类当中显示的调用本类的构造函数  :this

代码展示:

class MyClass
{
// 声明一个名为"myVal"的整型字段
public int myVal = 10; // 声明一个构造函数,该函数带一个名为"myVal"的参数
public MyClass(int myVal)
{
// "this"表示MyClass类的当前实例
// 在这里通过this可以在语义上区分成员名myVal和参数名myVal
this.myVal += myVal;
}
}

  

3)、声明索引器。(PS:这个会在后续的博客中更新)

代码展示:

 /// <summary>
///
/// </summary>
public NameValueCollection Attr = new NameValueCollection(); /// <summary>
/// /*************************/
/// /* this用法3:声明索引器 */
/// /*************************/
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string this[string key]
{
set
{
Attr[key] = value;
} get
{
return Attr[key];
}
}

4)、扩展对象的方法

代码展示:

/// <summary>
///Person 的摘要说明
/// </summary>
public class Person
{  /// <summary>
/// 性别
/// </summary>
public string Sex { set; get; }
} /// <summary>
/// 辅助类
/// </summary>
public static class Helper
{ /// <summary>
/// /*****************************/
/// /* this用法4:扩展对象的方法 */
/// /*****************************/
/// </summary>
/// <param name="item"></param>
/// <returns></returns>
public static string GetSex(this Person item)
{
return item.Sex;
}
}
调用: Person person = new Person();
person.GetSex();

  

本篇就到这里了,最后打个小广告:QQ群: .NET 一步步一幕幕  群号:590170361 (加群备注:博客园看到的)

.NET 基础 一步步 一幕幕[面向对象之new、this关键字]的更多相关文章

  1. .NET 基础一步步一幕幕[面向对象前言]

    面向对象前言 2017年的第一篇博文,好久不写博文了,赶紧补上,感觉在以前的<.NET 基础一步步一幕幕>系列博客中,简短的小知识点已经介绍的差不多的(PS:如果还有别的基础知识点我没有介 ...

  2. .NET 基础 一步步 一幕幕[面向对象之对象和类]

    对象和类 本篇正式进入面向对象的知识点简述: 何为对象,佛曰:一花一世界,一木一浮生,一草一天堂,一叶一如来,一砂一极乐,一方一净土,一笑一尘缘,一念一清静.可见"万物皆对象". ...

  3. .NET 基础 一步步 一幕幕[面向对象之方法、方法的重载、方法的重写、方法的递归]

    方法.方法的重载.方法的重写.方法的递归 方法: 将一堆代码进行重用的一种机制. 语法: [访问修饰符] 返回类型 <方法名>(参数列表){ 方法主体: } 返回值类型:如果不需要写返回值 ...

  4. .NET 基础 一步步 一幕幕[面向对象之构造函数、析构函数]

    构造函数.析构函数 构造函数: 语法: //无参的构造函数 [访问修饰符] 函数名() :函数名必须与类名相同. //有参的构造函数 [访问修饰符] 函数名(参数列表):函数名必须与类名相同. 作用: ...

  5. .NET 基础 一步步 一幕幕[面向对象之静态、非静态]

    静态.非静态 先来看一段代码来区分静态与非静态: using System; using System.Collections.Generic; using System.Linq; using Sy ...

  6. .NET 基础 一步步 一幕幕[面向对象之堆、栈、引用类型、值类型]

    堆.栈.引用类型.值类型 内存分为堆和栈(PS:还有一种是静态存储区域 [内存分为这三种]),值类型的数据存储在栈中,引用类型的数据存储在堆中. 堆.栈: 堆和栈的区别: 栈是编译期间就分配好的内存空 ...

  7. .NET 基础 一步步 一幕幕 [前言]

    .NET 基础 一步步 一幕幕 [前言部分] 本人小白一枚,虽然说从去年就开通博客了,到现在也没有写多少东东,虽然工作了,也没有更好得总结.故此重新祭出博客园法宝,修炼技术,争取早日走上大神之位. 故 ...

  8. .NET基础 一步步 一幕幕[循环、逻辑语句块]

    循环.逻辑语句块   好久不写博客了,断更了好几天了,从上周五到今天,从北京到上海,跨越了1213.0公里,从一个熟悉的城市到陌生的城市,还好本人适应力比较好,还有感谢小伙伴的接风咯,一切都不是事,好 ...

  9. .NET 基础 一步步 一幕幕 [.NET 简介]

    .NET 简介 .NET是 Microsoft XML Web services 平台.是微软用来实现XML,Web Services,SOA(面向服务的体系结构service-oriented ar ...

随机推荐

  1. Objective-C 实例方法可见度,方法

    一 实例方法可见度,方法 1.实例变量的可见度 可见度                                                                       特点 ...

  2. 使用EasyUI导入的js顺序

    使用Jquery Easy UI要导入的js顺序<1>.引用Jquery的Js文件<script src="jquery-easyui-1.3.4/jquery-1.8.0 ...

  3. [转]一个备份MySQL数据库的简单Shell脚本

    本文翻译自 iSystemAdmin 的 <A Simple Shell Script to Backup MySQL Database> Shell脚本是我们写不同类型命令的一种脚本,这 ...

  4. Java线程(学习整理)--1--守护线程

    1.什么是守护线程? 今天老师讲解我才知道有守护线程这回事!原来守护线程经常存在于我们的身边,比如:一个免费的网页游戏,里面都会或多或少有些插入性的广告!! 一般情况下,我们不会去点击这些广告的,但是 ...

  5. ccui.ScrollView 扩展

    大多数游戏都有背包这个东西. 道具列表通常用 ScrollView 来实现. 这个ScrollView内部有一个Layout, 滑动都是由移动这个Layout来实现. 道具摆放通常从上往下, 从左到右 ...

  6. 【Ural1057】幂和的数量

    [题目描述] 写一个程序来计算区间[X,Y]内满足如下条件的整数个数:它恰好等于K个互不相等的B的整数幂之和. 举个例子.令X=15,Y=20,K=2,B=2.在这个例子中,区间[15,20]内有3个 ...

  7. PHPCMS(2)PHPCMS V9 环境搭建(转)

    转自:http://www.cnblogs.com/Braveliu/p/5072920.html PHPCMS V9的学习总结分为以下几点: [1]PHPCMS 简介 PHP原始为Personal ...

  8. js创建对象的三种方法:文本标识法和构造器函数法和返回对象的函数

    文本标识法和定义变量差不多,像这样 var obj = {name:'HanMM','2':'Dali'}; 函数构造器法  先创建一个对象函数 function Obj() { this.addre ...

  9. CentOS 6.8安装Python2.7.13

    查看当前系统中的 Python 版本 python --version 返回 Python 2.6.6 为正常. 检查 CentOS 版本 cat /etc/redhat-release 返回 Cen ...

  10. 【算法】简单选择排序 O(n^2) 不稳定的 C语言

    简单选择排序 一.算法描述 假设序列中有N个元素: 第1趟找到第1到N个元素之间最小的一个,与第1个元素进行交换 第2趟找到第2到N个元素之间最小的一个,与第2个元素进行交换 第3趟找到第3到N个元素 ...