using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
abstract class AbstractClass //抽象类可以包括抽象方法,这是普通类所不能的 ,抽象方法只能声明于抽象类中,且不包含任何实现,派生类必须覆盖它们。
//好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染
{
//当在差异较大的对象间寻求功能上的共性时,使用接口。 当在共性较多的对象间寻求功能上的差异时,使用抽象基类。
//抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能
//接口着重于CAN-DO关系类型,而抽象类则偏重于IS-A式的关系;
//接口多定义对象的行为;抽象类多定义对象的属性
//“接口不变”,是应该考虑的重要因素。所以,在由接口增加扩展时,应该增加新的接口,而不能更改现有接口。
//尽量将接口设计成功能单一的功能块,以.NET Framework为例,IDisposable、IDisposable、IComparable、IEquatable、IEnumerable等都只包含一个公共方法
//在抽象方法声明中不能使用 static 或 virtual 修饰符。
protected abstract string TestMethod();
protected string TestMothodtt()
{
return "";
}
protected string TestMothodt434t()
{
return "";
}
protected virtual string Test55()
{
return "";
}
}
class InheritClass : AbstractClass
{
//protected abstract string TestInheritMothod22();
protected string TestInheritMethod11()
{
return "";
}
protected override string TestMethod()
{
return "";
}
protected virtual string Test55()
{
return "";
}
}
public abstract class A //抽象类A
{
private int num = 0;
public int Num //抽象类包含属性
{
get
{
return num;
}
set
{
num = value;
}
}
public virtual int getNum() //抽象类包含虚方法
{
return num;
}
public void setNum(int n) // //抽象类包含普通方法
{
this.num = n;
}
public abstract void E(); //类A中的抽象方法E
}
public abstract class B : A //由于类B继承了类A中的抽象方法E,所以类B也变成了抽象类
{
}
public class C : B
{
public override void E() //重写从类A继承的抽象方法。如果类B自己还定义了抽象方法,也必须重写
{
//throw new Exception("The method or operation is not implemented.");
}
public void Eff() //重写从类A继承的抽象方法。如果类B自己还定义了抽象方法,也必须重写
{
//throw new Exception("The method or operation is not implemented.");
}
}
//泛型类的设计理念就是数据类型无关。
public class A<T>
{
T[] test = new T[100];
public T[] GenericArray
{
get
{
return test;
}
}
public T this[int index]
{
get
{
return test[index];
}
set
{
test[index] = value;
}
}
}
public class TestGeneric1
{
public void Test()
{
A<string> str = new A<string>();
str[4] = "hello";
str[5] = "world";
string[] strs = str.GenericArray;
foreach (string s in strs)
{
Console.Write(s);
}
//A<int> str44 = new A<int>();
//str44[4] = 4;
//str44[5] = 6;
//int[] strdd = str44.GenericArray;
//foreach (int s in strdd)
//{
// Console.Write(s);
//}
}
public static T GetValue<T>(Object value, T defaultValue)//GetValue<T>代表泛型方法,这种方法在调用时需传入方法的具体类型 ,前面的的T是返回类型
{
if (null == value || value is DBNull)
{
return defaultValue;
}
else
{
try
{
return (T)Convert.ChangeType(value, typeof(T));
}
catch
{
return defaultValue;
}
}
}
// 申明:
//public T Add<T>(T a,T b)
//{
// return a + b;
//}
//调用:
//float x = ...;
//float y = ...;
//float z = Add<float>(x, y);
}
public interface ITest //接口的成员包括方法、属性、索引器、事件 ,接口中的所有成员默认为public
{
//int x = 0;
int A
{
get;
set;
}
void Test();
//event EventHandler Event;
int this[int index]
{
get;
set;
}
}
public class Test33 : ITest
{
private int _a;
public int A
{
get
{
return _a;
}
set
{
_a = value;
}
}
public void Test()
{
}
public int this[int index]
{
get
{
return _a;
}
set
{
_a = value;
}
}
}
//----------------------------------------------------------------------
class Program444
{
class Class1<YG>
{
public Class1()
{
Console.WriteLine("一");
Console.WriteLine(typeof(Class1<YG>));
}
}
class Class2<Y> : Class1<Y>
{
public Class2()
{
Console.WriteLine("二");
Console.WriteLine(typeof(Class2<Y>));
}
}
static void Main44(string[] args)
{
Class1<int> mm = new Class1<int>();
Class2<double> nn = new Class2<double>();
}
//---------------------------------------------------------------
class b
{
public string a;
}
class b1 : b
{
public b1()
{
a = "b1";
}
}
class b2 : b
{
public b2()
{
a = "b2";
}
}
class c<T>
{ }
class c1 : c<b1>
{
}
class c2 : c<b2>
{
}
class a
{
public c<b> c;
}
private void fdsf()
{
a a1 = new a();
c1 c11 = new c1();
c2 c21 = new c2();
//a1.c = c11;//无法将类型“ConsoleApplication1.Program444.c1”隐式转换为“ConsoleApplication1.Program444.c<ConsoleApplication1.Program444.b”
//c11 = a1.c;
}
}
//-----------------------------------------------------------------------
public class A44<T>
{
public T1 getSth1<T1>(T1 t)
{
return t;
}
public void getSth2<T2>(T2 t)
{
}
//非泛型方法
public T getSth3(T t)
{
return t;
}
public T getSth4() //符合c#语法
{
return default(T);
}
}
public class fd
{
public void fds()
{
A44<int> dd444 = new A44<int>();
string i = dd444.getSth1<string>("dd");
dd444.getSth3(44);
}
}
}
//--------------------------
delegate string GenericDelete<T>(T value);
class test
{
static string F(int i)
{
return "SHY520";
}
static string G(string s)
{
return "SHY520";
}
static void Main44()
{
GenericDelete<string> G1 = G;
GenericDelete<int> G2 = new GenericDelete<int>(F);
}
}
//----------------------------------------------------------
//要注意的是,泛型方法被覆盖时,约束被默认继承,不需要重新指定约束关系
abstract class Parent
{
public abstract K TEST<K, V>(K k, V v) where K : V;
}
class Child : Parent
{
public override T TEST<T, S>(T t, S s)
{
return t;
}
}
//---------------------------------------------
//C#中的泛型只支持显示的约束,因为这样才能保证C#所要求的类型安全,但显示的约束并非时必须的,如果不加约束,泛型类型参数将只能访问System.Object类型中的公有方法。“显式约束”由where子句表达,可以指定“基类约束”,“接口约束”,“构造器约束”,“值类型/引用类型约束”共四种约束。下面的例子来源于李建忠老师的讲座PPT。
//基类约束:
class A
{
public void F1() { }
}
class B
{
public void F2() { }
}
class C<S, T>
where S : A // S继承自A
where T : B // T继承自B
{
// 可以在类型为S的变量上调用F1,
// 可以在类型为T的变量上调用F2
}
//接口约束
interface IPrintable
{
void Print();
int dd
{
get;
set;
}
}
interface IComparable<T>
{
int CompareTo(T v);
}
interface IKeyProvider<T>
{
T GetKey();
}
class Dictionary44<K, V>
where K : IComparable<K>
where V : IPrintable, IKeyProvider<K>
{
// 可以在类型为K的变量上调用CompareTo,
// 可以在类型为V的变量上调用Print和GetKey
}
//构造器约束-------------------------------------
class A2545435
{
// private A2545435() { }
}
class A233 : A2545435
{
}
class A2
{
public A2() { }
}
class B2
{
public B2() { }
public B2(int i) { }
}
//new 约束指定泛型类声明中的任何类型参数都必须有公共的无参数构造函数。如果要使用 new 约束,则该类型不能为抽象类型。
class C<T> where T : new()
{
//可以在其中使用T t=new T();
T t = new T();
}
class sss
{
C<A2> c = new C<A2>(); //可以,A有无参构造器
C<B2> c2 = new C<B2>(); //错误,B没有无参构造器
}
//值/引用类型约束------------------------------------------------------
public struct A3 { }
public class B3 { }
class C3<T> where T : struct
{
// T在这里面是一个值类型
}
class GGG
{
C3<A3> c = new C3<A3>(); //可以,A是一个值类型
// C3< B3> c=new C3< B3>(); //错误,B是一个引用类型
}
// end ------------------------------------------------------------