1.多态
1.抽象类(abstract)
1.您不能创建一个抽象类的实例。
2.您不能在一个抽象类外部声明一个抽象方法。
3. 通过在类定义前面放置关键字 sealed,可以将类声明为密封类。当一个类被声明为 sealed 时,它不能被继承。抽象类不能被声明为 sealed。
using System;
namespace PolymorphismApplication
{
abstract class Shape
{
abstract public int area();
}
class Rectangle: Shape
{
private int length;
private int width;
public Rectangle( int a=0, int b=0)
{
length = a;
width = b;
}
public override int area ()
{
Console.WriteLine("Rectangle 类的面积:");
return (width * length);
}
}
class RectangleTester
{
static void Main(string[] args)
{
Rectangle r = new Rectangle(10, 7);
double a = r.area();
Console.WriteLine("面积: {0}",a);
Console.ReadKey();
}
}
}
2.虚函数
using System;
using System.Collections.Generic;
public class Shape
{
public int X { get; private set; }
public int Y { get; private set; }
public int Height { get; set; }
public int Width { get; set; }
// 虚方法
public virtual void Draw()
{
Console.WriteLine("执行基类的画图任务");
}
}
class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("画一个圆形");
base.Draw();
}
}
class Rectangle : Shape
{
public override void Draw()
{
Console.WriteLine("画一个长方形");
base.Draw();
}
}
class Triangle : Shape
{
public override void Draw()
{
Console.WriteLine("画一个三角形");
base.Draw();
}
}
class Program
{
static void Main(string[] args)
{
// 创建一个 List<Shape> 对象,并向该对象添加 Circle、Triangle 和 Rectangle
var shapes = new List<Shape>
{
new Rectangle(),
new Triangle(),
new Circle()
};
// 使用 foreach 循环对该列表的派生类进行循环访问,并对其中的每个 Shape 对象调用 Draw 方法
foreach (var shape in shapes)
{
shape.Draw();
}
Console.WriteLine("按下任意键退出。");
Console.ReadKey();
}
}
2.运算符重载
using System;
namespace OperatorOvlApplication
{
class Box
{
private double length; // 长度
private double breadth; // 宽度
private double height; // 高度
public double getVolume()
{
return length * breadth * height;
}
public void setLength( double len )
{
length = len;
}
public void setBreadth( double bre )
{
breadth = bre;
}
public void setHeight( double hei )
{
height = hei;
}
// 重载 + 运算符来把两个 Box 对象相加
public static Box operator+ (Box b, Box c)
{
Box box = new Box();
box.length = b.length + c.length;
box.breadth = b.breadth + c.breadth;
box.height = b.height + c.height;
return box;
}
}
class Tester
{
static void Main(string[] args)
{
Box Box1 = new Box(); // 声明 Box1,类型为 Box
Box Box2 = new Box(); // 声明 Box2,类型为 Box
Box Box3 = new Box(); // 声明 Box3,类型为 Box
double volume = 0.0; // 体积
// Box1 详述
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// Box2 详述
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// Box1 的体积
volume = Box1.getVolume();
Console.WriteLine("Box1 的体积: {0}", volume);
// Box2 的体积
volume = Box2.getVolume();
Console.WriteLine("Box2 的体积: {0}", volume);
// 把两个对象相加
Box3 = Box1 + Box2;
// Box3 的体积
volume = Box3.getVolume();
Console.WriteLine("Box3 的体积: {0}", volume);
Console.ReadKey();
}
}
}
3.接口和接口继承
using System;
interface IParentInterface
{
void ParentInterfaceMethod();
}
interface IMyInterface : IParentInterface
{
void MethodToImplement();
}
class InterfaceImplementer : IMyInterface
{
static void Main()
{
InterfaceImplementer iImp = new InterfaceImplementer();
iImp.MethodToImplement();
iImp.ParentInterfaceMethod();
}
public void MethodToImplement()
{
Console.WriteLine("MethodToImplement() called.");
}
public void ParentInterfaceMethod()
{
Console.WriteLine("ParentInterfaceMethod() called.");
}
}
4.命名空间
using System;
using first_space;
using second_space;
namespace first_space
{
class abc
{
public void func()
{
Console.WriteLine("Inside first_space");
}
}
}
namespace second_space
{
class efg
{
public void func()
{
Console.WriteLine("Inside second_space");
}
}
}
class TestClass
{
static void Main(string[] args)
{
abc fc = new abc();
efg sc = new efg();
fc.func();
sc.func();
Console.ReadKey();
}
}
5.特性
1.参数 validon 规定特性可被放置的语言元素。它是枚举器 AttributeTargets 的值的组合。默认值是 AttributeTargets.All。
2.参数 allowmultiple(可选的)为该特性的 AllowMultiple 属性(property)提供一个布尔值。如果为 true,则该特性是多用的。默认值是 false(单用的)。
3. 参数 inherited(可选的)为该特性的 Inherited 属性(property)提供一个布尔值。如果为 true,则该特性可被派生类继承。默认值是 false(不被继承)。
[AttributeUsage(
validon,
AllowMultiple=allowmultiple,
Inherited=inherited
)]
1.Obsolete
这个预定义特性标记了不应被使用的程序实体。它可以让您通知编译器丢弃某个特定的目标元素。例如,当一个新方法被用在一个类中,但是您仍然想要保持类中的旧方法,您可以通过显示一个应该使用新方法,而不是旧方法的消息,来把它标记为 obsolete(过时的)。
规定该特性的语法如下:
using System;
public class MyClass
{
[Obsolete("Don't use OldMethod, use NewMethod instead", true)]
static void OldMethod()
{
Console.WriteLine("It is the old method");
}
static void NewMethod()
{
Console.WriteLine("It is the new method");
}
public static void Main()
{
OldMethod();
}
}
2.创建自定义特性(Attribute)
而所谓的自定义消息通过 AttributeUsage 进行定义,通常情况下就是写一个类继承自 Attribute,当然标签特性也要加上。
[AttributeUsage(
AttributeTargets.Class|
AttributeTargets.Constructor|
AttributeTargets.Field|
AttributeTargets.Method|
AttributeTargets.Property|
AttributeTargets.Property,
AllowMultiple=true
)]
public class DebugInfo:System.Attribute{
//constructor
//field1......
//method......
//Property......
}
[DebugInfo构造函数]
class Rectangle() {
//[DebugInfo构造函数]
//方法1
[DebugInfo(55,“Zara Ali”,"19/10/2012")]
public double SayHello(){
//do somethindg;
//
}
}
而所谓的反射则是把类或方法的标签信息提取出来。
比如:
Rectangele rect=new Rectangle();
Type type=typeof(Rectangle);
foreach(object attributes in type.GetCustomAttributes(false)) {
DeBugInfo dbi=(DeBugInfo)attributes; //打印dbi属性
}
3.conditional
#define BUG
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Threading;
using System.Diagnostics;
namespace helloworld
{
public class Myclass
{
[Conditional("BUG")]
public static void M1(string msg)
{
Console.WriteLine(msg);
}
[Conditional("deBUG")]
public static void M2(string msg)
{
Console.WriteLine(msg);
}
[Conditional("BUG")]
public static void M3(string msg)
{
Console.WriteLine(msg);
}
[Conditional("kk")]
public static void M4(string msg)
{
Console.WriteLine(msg);
}
}
class Program
{
static void Main(string[] args)
{
Myclass.M1("456");
Myclass.M2("845");
Myclass.M3("dadasd");
Myclass.M4("456xcvc");
Console.WriteLine("Main thread ID is:" );
Console.ReadKey();
}
}
}
将头部的#define BUG就会运行M1和M3,定义为#define kk就将会只运行M4方法。
但是注意如果没有写[]的都会执行,所以一般加[]attrible时候,常常看见如果有加一般每个方法上面都会加。
6.反射
反射(Reflection)有下列用途:
它允许在运行时查看特性(attribute)信息。
它允许审查集合中的各种类型,以及实例化这些类型。
它允许延迟绑定的方法和属性(property)。
它允许在运行时创建新类型,然后使用这些类型执行一些任务。
using System;
using System.Reflection;//System.Reflection 类的 MemberInfo用于发现与类相关的特性(attribute)。
namespace BugFixApplication
{
// 一个自定义特性 BugFix 被赋给类及其成员
[AttributeUsage
#region//定义了特性能被放在那些前面
(AttributeTargets.Class |//规定了特性能被放在class的前面
AttributeTargets.Constructor |//规定了特性能被放在构造函数的前面
AttributeTargets.Field |//规定了特性能被放在域的前面
AttributeTargets.Method |//规定了特性能被放在方法的前面
AttributeTargets.Property,//规定了特性能被放在属性的前面
#endregion
AllowMultiple = true)]//这个属性标记了我们的定制特性能否被重复放置在同一个程序实体前多次。
public class DeBugInfo : System.Attribute//继承了预定义特性后的自定义特性
{
private int bugNo;
private string developer;
private string lastReview;
public string message;
public DeBugInfo(int bg,string dev,string d)//构造函数,接收三个参数并赋给对应实例
{
this.bugNo = bg;
this.developer = dev;
this.lastReview = d;
}
#region//定义对应的调用,返回对应值value
public int BugNo
{
get
{
return bugNo;
}
}
public string Developer
{
get
{
return developer;
}
}
public string LastReview
{
get
{
return lastReview;
}
}
//前面有public string message;
public string Message//定义了可以通过Message = "",来对message进行赋值。
//因为不在构造函数中,所以是可选的
{
get
{return message;}
set
{message = value;}
}
/*
* 这部分可以简写如下
* public string Message{get;set;}
*/
}
#endregion
[DeBugInfo(45, "Zara Ali", "12/8/2012",
Message = "Return type mismatch")]
[DeBugInfo(49, "Nuha Ali", "10/10/2012",
Message = "Unused variable")]//前面定义时的AllowMultiple=ture允许了多次使用在同一地方
class Rectangle
{
protected double length;
protected double width;//定义两个受保护的(封装)的成员变量
public Rectangle(double l,double w)//构造函数,对两个成员变量进行初始化,公开的
{
length = l;
width = w;
}
[DeBugInfo(55, "Zara Ali", "19/10/2012",
Message = "Return type mismatch")]
public double GetArea()
{
return length * width;
}
[DeBugInfo(56, "Zara Ali", "19/10/2012")]//因为message是可选项,所以可以不给出
//不给出即为null,为空白
public void Display()
{
Console.WriteLine("Length: {0}", length);
Console.WriteLine("Width:{0}", width);
Console.WriteLine("Area:{0}", GetArea());//常规打印
}
}
class ExecuteRectangle
{
static void Main(string[] args)//程序入口
{
Rectangle r = new Rectangle(4.5, 7.5);//实例化
r.Display();//执行打印长、宽、面积
Type type = typeof(Rectangle);//让type对应这个Rectangle类
// 遍历 Rectangle 类的特性
foreach (Object attributes in type.GetCustomAttributes(false))//遍历Rectangle的所有特性
{
DeBugInfo dbi = (DeBugInfo)attributes;//强制转换
if(null != dbi)//dbi非空
{
Console.WriteLine("Bug on: {0}", dbi.BugNo);
Console.WriteLine("Developer: {0}", dbi.Developer);
Console.WriteLine("Last REviewed: {0}", dbi.LastReview);
Console.WriteLine("Remarks: {0}", dbi.Message);
}
}
// 遍历方法特性
foreach (MethodInfo m in type.GetMethods())//遍历Rectangle类下的所有方法
{
foreach (Attribute a in m.GetCustomAttributes(true))//遍历每个方法的特性
{
DeBugInfo dbi = a as DeBugInfo;//通过 object 声明对象,是用了装箱和取消装箱的概念.
//也就是说 object 可以看成是所有类型的父类。
//因此 object 声明的对象可以转换成任意类型的值。
//通过拆装箱代替强制转换
if (null !=dbi)//同理打印
{
Console.WriteLine("BugFixApplication no: {0},for Method: {1}", dbi.BugNo, m.Name);
Console.WriteLine("Developer:{0}", dbi.Developer);
Console.WriteLine("Last Reviewed: {0}", dbi.LastReview);
Console.WriteLine("Remarks: {0}", dbi.Message);
}
}
}
Console.ReadKey();
}
}
}
7.C#数据结构使用
(1)字典的建立 查找 和字符串的分割,代替。
public class Solution {
public string MostCommonWord(string paragraph, string[] banned) {
paragraph=paragraph.Replace(",", " ").Replace(".", " ").Replace("!"," ").Replace("?"," ")
.Replace(";"," ").Replace("'"," ");
paragraph = paragraph.ToLower();
//StringSplitOptions.RemoveEmptyEntries 多个连续空格会当作一个空格
string[] result = paragraph.Split(" ", StringSplitOptions.RemoveEmptyEntries);
Dictionary<string, int> dic = new Dictionary<string, int>();
foreach(string i in result){
if(dic.ContainsKey(i)){
dic[i]++;
}else{
dic.Add(i,1);
}
}
foreach(string i in banned){
dic.Remove(i);
}
return dic.OrderByDescending(kvp => kvp.Value).First().Key;
}
}