C#的函数、结构体、类、方法,继承、接口
·
1. 字段与属性的本质区别
字段(Field)是类或结构体中存储数据的变量,而属性(Property)是访问字段的封装方式。
核心区别:
-
字段是数据存储单元,属性是数据访问的接口
-
字段可直接访问,属性通过
get/set方法控制访问逻辑 -
属性支持数据验证、计算和变更通知等高级功能
public class Person
{
// 私有字段(数据存储)
private string _name;
private int _age;
// 自动实现属性(简化语法)
public string Address { get; set; }
// 带验证逻辑的属性
public string Name
{
get => _name;
set
{
if (string.IsNullOrEmpty(value))
throw new ArgumentException("Name cannot be empty");
_name = value;
}
}
// 计算属性
public int BirthYear
{
get => DateTime.Now.Year - _age;
}
// 构造函数初始化
public Person(string name, int age)
{
Name = name;
Age = age;
}
}
2. 访问修饰符详解
C# 提供了 5 种访问修饰符,控制成员的可见性:
| 修饰符 | 访问权限描述 |
|---|---|
public |
无访问限制 |
private |
仅在定义类型内部可访问 |
protected |
在定义类型及其派生类中可访问 |
internal |
在当前程序集(项目)内可访问 |
protected internal |
同时满足 protected 和 internal |
3. 函数(静态方法)与方法的差异
在 C# 中,"函数" 通常指静态方法,而 "方法" 指实例方法:
public static class MathHelper
{
// 静态方法(函数):不依赖实例
public static double CalculateCircleArea(double radius)
{
return Math.PI * radius * radius;
}
}
public class Calculator
{
private int _memoryValue;
// 实例方法:依赖对象状态
public void AddToMemory(int value)
{
_memoryValue += value;
}
// 静态方法:不依赖对象状态
public static int Add(int a, int b) => a + b;
}
// 调用示例
double area = MathHelper.CalculateCircleArea(5);
int sum = Calculator.Add(3, 4);
Calculator calc = new Calculator();
calc.AddToMemory(10); // 访问实例方法
4. 结构体(Struct)与类(Class)的本质区别
结构体是值类型,类是引用类型,二者的核心差异体现在内存分配和使用方式上:
// 值类型:结构体
public struct Point
{
public double X { get; set; }
public double Y { get; set; }
// 结构体构造函数必须初始化所有属性
public Point(double x, double y)
{
X = x;
Y = y;
}
// 方法:计算到原点的距离
public double DistanceToOrigin() => Math.Sqrt(X * X + Y * Y);
}
// 引用类型:类
public class ComplexNumber
{
public double Real { get; set; }
public double Imaginary { get; set; }
public ComplexNumber(double real, double imaginary)
{
Real = real;
Imaginary = imaginary;
}
// 方法:复数加法
public ComplexNumber Add(ComplexNumber other)
{
return new ComplexNumber(Real + other.Real, Imaginary + other.Imaginary);
}
}
// 使用差异
Point p1 = new Point(3, 4);
Point p2 = p1; // 值复制
p2.X = 5; // 不影响p1
ComplexNumber c1 = new ComplexNumber(1, 2);
ComplexNumber c2 = c1; // 引用复制
c2.Real = 3; // 同时修改c1和c2
5. 继承与多态的实现
C# 支持单继承和多态,通过 virtual、override 和 abstract 关键字实现:
// 抽象基类
public abstract class Shape
{
public string Color { get; set; }
protected Shape(string color)
{
Color = color;
}
// 抽象方法:必须在子类中实现
public abstract double Area();
// 虚方法:可在子类中重写
public virtual string GetInfo()
{
return $"Color: {Color}, Area: {Area():F2}";
}
}
// 具体子类
public class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius, string color) : base(color)
{
Radius = radius;
}
// 实现抽象方法
public override double Area() => Math.PI * Radius * Radius;
// 重写虚方法
public override string GetInfo()
{
return $"Circle - {base.GetInfo()}";
}
}
public class Rectangle : Shape
{
public double Width { get; set; }
public double Height { get; set; }
public Rectangle(double width, double height, string color) : base(color)
{
Width = width;
Height = height;
}
public override double Area() => Width * Height;
public override string GetInfo()
{
return $"Rectangle - {base.GetInfo()}";
}
}
// 多态示例
Shape[] shapes = new Shape[]
{
new Circle(5, "Red"),
new Rectangle(4, 6, "Blue")
};
foreach (var shape in shapes)
{
Console.WriteLine(shape.GetInfo());
// 输出:
// Circle - Color: Red, Area: 78.54
// Rectangle - Color: Blue, Area: 24.00
}
6. 接口的设计与实现
接口定义了行为契约,支持多实现和依赖倒置原则:
// 定义多个接口
public interface IRenderable
{
void Render();
}
public interface IAnimatable
{
void Animate();
}
// 实现多个接口
public class Button : IRenderable, IAnimatable
{
public string Text { get; set; }
public Button(string text)
{
Text = text;
}
// 显式实现接口方法
void IRenderable.Render()
{
Console.WriteLine($"Rendering button: {Text}");
}
// 隐式实现接口方法
public void Animate()
{
Console.WriteLine("Animating button...");
}
}
// 接口作为参数类型(依赖注入)
public class UIManager
{
public void DrawUI(IRenderable element)
{
element.Render();
}
}
// 使用示例
Button btn = new Button("Submit");
UIManager manager = new UIManager();
manager.DrawUI(btn); // 输出: Rendering button: Submit
关键补充知识
1.密封类与方法:禁止继承或重写
public sealed class FinalClass // 密封类不能被继承
{
public void DoSomething() { }
}
public class BaseClass
{
public virtual void Method() { }
}
public class DerivedClass : BaseClass
{
public sealed override void Method() { } // 密封此方法,禁止进一步重写
}
2.接口默认实现(C# 8.0+):
public interface ILogger
{
// 默认实现
void Log(string message) => Console.WriteLine($"[INFO]: {message}");
// 抽象方法(必须实现)
void LogError(string error);
}
public class ConsoleLogger : ILogger
{
public void LogError(string error) => Console.WriteLine($"[ERROR]: {error}");
// 可以选择性重写默认方法
public void Log(string message) => Console.WriteLine($"[CUSTOM]: {message}");
}
3.扩展方法:为现有类型添加新方法
public static class StringExtensions
{
public static bool IsPalindrome(this string str)
{
if (string.IsNullOrEmpty(str)) return false;
int left = 0;
int right = str.Length - 1;
while (left < right)
{
if (str[left] != str[right]) return false;
left++;
right--;
}
return true;
}
}
// 使用扩展方法
string test = "radar";
bool result = test.IsPalindrome(); // true
4.静态类与静态构造函数:
public static class Configuration
{
public static string ApiKey { get; private set; }
public static int Timeout { get; private set; }
// 静态构造函数(自动调用,且只调用一次)
static Configuration()
{
ApiKey = Environment.GetEnvironmentVariable("API_KEY") ?? "default_key";
Timeout = int.TryParse(Environment.GetEnvironmentVariable("TIMEOUT"), out int timeout)
? timeout : 3000;
}
}
5.抽象类:包含抽象方法的类,不能实例化
public abstract class Shape {
public abstract double Area(); // 抽象方法
}
6.密封类:禁止被继承
public sealed class FinalClass { } // 不能被继承
7.接口默认实现(C# 8.0+):
public interface ILogger {
void Log(string message) => Console.WriteLine($"[Log]: {message}");
}
8.扩展方法:为现有类型添加方法
public static class StringExtensions {
public static bool IsNullOrEmpty(this string str) {
return string.IsNullOrEmpty(str);
}
}
核心区别总结
| 概念 | 类型 | 继承规则 | 内存分配 | 适用场景 |
|---|---|---|---|---|
| 函数 | 静态方法 | 无 | 方法区 | 工具类、纯计算逻辑 |
| 结构体 | 值类型 | 不可继承,可实现接口 | 栈或对象内 | 轻量数据(坐标、时间) |
| 类 | 引用类型 | 单继承,支持多接口 | 堆 | 复杂对象(用户、订单) |
| 方法 | 类的成员 | 可重写、重载 | 随对象或类型 | 对象行为的具体实现 |
| 继承 | 类的关系 | 单继承(每个类一个父类) | 共享父类成员 | 代码复用、多态 |
| 接口 | 契约 | 可多实现 | 无(仅定义规范) | 定义行为、解耦组件 |
更多推荐


所有评论(0)