C# study notes–Three major characteristics of object-oriented
C# core
Object-oriented–Encapsulation
Use programs to abstract the real world (everything is an object) to implement functions through programming.
Three major features: encapsulation, inheritance, and polymorphism.
Classes and Objects
Declaration location: namespace
Style: class class name{}
Naming: Pascal nomenclature (first letter capitalized)
Instantiate object: Create a new object based on the class. Person p=new Person();
Member variable
- Declared in a class statement block
- Used to describe the characteristics of objects
- Can be any variable type
- No limit on quantity
- Whether to assign a value is determined according to requirements
enum E_SexType
{
Man,
Woman
}
struct Position{}//Position structure
class Pet{}//Pet class
//Member variables in the class
class Person
{
public string name="TonyChang";//Different from the structure--the initial value can be assigned by default
public int age=21;
public E_SexType sex;
public Person bestFriend;//Different from structures---classes can have member types of the same type (essentially because classes are reference types, but cannot be instantiated, preventing repeated new and falling into an infinite loop)
public Position pos;
public Pet pet;
}
Default value for member type:
Value type: number is 0, bool
type is false
Reference type: null
View (int type) default value: default(int)
Supplement: class is a reference type, and the value type is also placed in the heap.
Member method
- Declared in a class statement block
- Used to describe object behavior
- There are no restrictions on its return value parameters
- No limit on quantity
- Pascal nomenclature (first letter capitalized)
Member methods can only be called after they are instantiated. A specific behavior (method) of an object must be called by a specific object.
//Member method
class Person
{
public string name;
public int age;
public void Speak()
{
Console.WriteLine("Hello!");
}
}
//Usage of member methods
Person p=new Person;
p.Speak();
Constructor and Destructor
There is a parameterless constructor by default, and classes can allow themselves to declare parameterless constructors, but structures cannot.
Once there is a custom constructor, the default no-argument constructor becomes invalid!
Constructor:
- public modification
- No return value, the name is the same as the class name
class Person
{
public string name;
public int age;
//Constructor
publicPerson()
{
name="TonyChang";
age=21;
}
//At this time, first call the constructor of the age parameter and then call the constructor of the two parameters.
public Person(string name,int age):this(age)
{
this.name=name;
this.age=age;
}
publicPerson(string name)
{
this.name=name;
}
publicPerson(int age)
{
this.age=age;
}
}
Special constructor, call this parameterless constructor before calling this function.
public Person(int age):this()
{
this.age=age;
}
Destructor:
Due to the automatic garbage collection mechanism in C#, destructors are generally not used.
The destructor is called when the garbage is actually collected.
~Person(){}
//Destructor
Member Attribute:
Used to protect member variables and add logical processing for the acquisition and assignment of member attributes.
//Member attributes Pascal nomenclature
class Person
{
private string name;
public string Name
{
get{
return name;
}
set{
name=value;
}
}
private int age;
public int Age
{
//The age cannot be obtained (or delete the set setting to indicate that the age cannot be obtained)
private get=>age;
//You can set the age
set
{
age=value;
}
}
//additional:
//Automatic member attributes (for members with no special needs)
public float Height
{
get;
set;
}
}
indexer
An object can be accessed by index just like an array.
Note: Indexers are also supported in structures.
//Indexer
class Person
{
private string name;
private int age;
private Person[] friends;
private int[,] arry;
//Indexer
public Person this[int index]
{
get
{
return friends[index];
}
set
{
//You can write some control logic here
friends[inuals("123456"))
{
}
String or StringBuilder?
String has many types of methods and is more convenient and flexible to use, but its performance is not as good as StringBuilder and it produces less garbage than StringBuilder
It is better to use StringBuilder for strings that need to be modified frequently.
How to optimize memory?
- Save memory
- Less new objects and less garbage
- Use static appropriately
- Use String and StringBuilder appropriately
- Reduce GC generation
The difference between a structure and a class
- Storage location: The structure is a value type and is stored in the stack. The class is a reference type and is stored in the heap
- Member variables in structures cannot be assigned initial values, but in classes they can
- Structures have encapsulation properties but do not have inheritance and polymorphism, while classes have them
- The structure does not have inheritance characteristics, so it cannot be modified with the protected protection modifier
- After the structure declares a parameterized constructor, the parameterless constructor will not be rejected
- Structures cannot declare destructors, but classes can
- Structures need to initialize all member variables in the constructor, but classes are free
- Structures cannot be modified by static, there is no static structure, and the class is arbitrary
- A structure cannot declare the same structure variable as itself internally (it will create infinite creations…stack overflow), but a class can (because it is a reference)
- Structures can inherit interface (classes and structures cannot be inherited)
How to choose structures and classes:
- If you want to use inheritance and polymorphism, directly eliminate structures, such as players and monsters
- When the stored object is a collection of data, priority is given to structures, such as vectors, coordinates, etc.
- Basically, if you often change the assignment object and do not want the original value to change, use a structure (value type, copy, does not affect itself), such as coordinates, vectors, rotation angles, etc.
The difference between abstract classes and interfaces
Same points:
- Can be inherited
- Neither can be instantiated directly
- Can contain method declarations
- Subclasses must implement unimplemented methods
- They all follow the Liskov substitution principle (parent class installs subclass)
Difference:
- Abstract classes can have constructors, but interfaces cannot
- Abstract classes can only be inherited from a single inheritance, interfaces can be inherited from multiple ones
- Abstract classes can have member variables, but interfaces cannot
- Abstract classes can declare member methods, virtual methods, abstract methods, and static methods, while interfaces can only declare abstract methods without implementation
- Abstract class methods can use access modifiers; it is recommended not to write them in the interface, and the default is public
How to choose abstract classes and interfaces
Represents the selected abstract class of the object and represents the interface used for behavioral expansion. For the same behavior of different objects, we can abstract the behavior and implement it with interfaces.
Seven principles of object-oriented
Overall goal: high cohesion, low coupling
Reduce calls to other classes within a class and reduce the complexity of interactions between modules.
- Single responsibility principle (one class focuses on one function)
- Richter substitution principle (parent classes can contain subclasses)
- Opening and closing principle (open to expansion, closed to modification, keep open and expanded, reduce modification)
- Dependency inversion principle (depend on abstraction, not on abstract concrete)
- Dimit Principle (Principle of Minimum Knowledge, Don’t Talk to Strangers)
- Interface isolation principle (an interface should not provide too many functions,)
- Principles of compositional reuse (try to use compositional reuse to implement functions and reduce inheritance of highly coupled behaviors)