Deep copy Vs soft copy
soft copy: 참조 변수만을 copy 하는것 결국 같은 data를 가리킴
Deep copy: 새로운 객체를 만들어서 copy 하는것
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _210525_001
{
class MyClass
{
public int MyFeild1;
public int MyFeild2;
public MyClass DeepCopy() // 새롭개 객체를 만들어서 자기자신을 member 변수들을 넣어준다.
{
MyClass newCopy = new MyClass();
newCopy.MyFeild1 = this.MyFeild1;
newCopy.MyFeild2 = this.MyFeild2;
return newCopy;
}
}
class MainApp
{
static void Main(string[] args)
{
Console.WriteLine("Shallow Copy");
{ // 괄호는 스택 영역임 heap 영역이 사라 지진 않는다.
// 즉 스택 영연인 source 와 target 은 사라진다.
MyClass source = new MyClass();
source.MyFeild1 = 10;
source.MyFeild2 = 20;
MyClass target = source;
target.MyFeild2 = 30;
Console.WriteLine($"{source.MyFeild1} , {source.MyFeild2}");
Console.WriteLine($"{target.MyFeild1} , {target.MyFeild2}");
}
Console.WriteLine("Deep copy");
{
MyClass source = new MyClass();
source.MyFeild1 = 10;
source.MyFeild2 = 20;
MyClass target = source.DeepCopy();
target.MyFeild2 = 30;
Console.WriteLine($"{source.MyFeild1} , {source.MyFeild2}");
Console.WriteLine($"{target.MyFeild1} , {target.MyFeild2}");
}
}
}
}
garbage collector : 문제가 있음
cpu 가 굉장히 바쁠때 garbage collector 가 동작된다면. 이는 필요한 메모리를 확보하는 것임으로 효율적이라 할 수도 있지만 만약 정말 바쁠때 garbage collector 가 동작한다면 garbage collector 또한 메모리를 차지 하기 때문에 이는 문제를 발생 시킬 수 있다.
생성자의 오버로딩
생성자의 경우 생성자 내에서 오버로딩한 생성자를 부르고 싶다면 :this() 와 같이 특이한 문법을 사용해야한다.
일반적인 메소드 내에서 오버로딩한 메소드를 부르고 싶다면 그냥 부르면 동작한다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _210525_002
{
class Smart
{
private string Name;
private string Address;
public Smart() :this("무명", "미기입") // 생성자가 생성자 호출 하는 방법
{
Console.WriteLine("디폴트 생성자");
}
public Smart(string Name) : this(Name, "미기입") // 생성자가 생성자 호출 하는 방법
{
Console.WriteLine("매개변수 1개 생성자");
}
public Smart(string Name, string Address) // 실제로 사용되는 함수
{
this.Name = Name;
this.Address = Address;
Console.WriteLine("매개변수 2개 생성자");
}
// 생성자의 경우에만 :this() 와 같은 문법으로 사용하고
// 보통의 메서드의 overloading 의 경우에는 함수내에서 그냥 호출 가능하다.
public void Test()
{
Test("무명", "미기입"); // 그냥 부르면 온다.
Console.WriteLine("디폴트 test");
}
public void Test(string Name)
{
Test(Name, "미기입");
Console.WriteLine("매개변수 1개 test");
}
public void Test(string Name, string Address)
{
this.Name = Name;
this.Address = Address;
Console.WriteLine("매개변수 2개 test");
}
}
class Program
{
static void Main(string[] args)
{
Smart aSmart = new Smart();
aSmart.Test();
}
}
}
상속
class 자식 : 부모
부모 클래스가 먼저 생성되고 그후에 자식 클래스가 생성된다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Parents
{
public Parents()
{
Console.WriteLine("Parent 디폴트 생성자 호출");
}
~Parents()
{
Console.WriteLine("Parent 소멸자 호출");
}
}
class Child : Parents // Child 는 Parenets 를 상속받음
{
public Child()
{
Console.WriteLine("child 디폴트 생성자 호출");
}
~Child()
{
Console.WriteLine("child 소멸자 호출");
}
}
class Program
{
static void Main(string[] args)
{
Child aChild = new Child();
}
}
base
부모의 생성자 호출
또는 부모의 member 호출 this 와 비슷하다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class A
{
public int aNum;
public A(int Num)
{
aNum = Num;
}
public A(int Num1, int Num2)
{
aNum = Num1;
}
}
class B:A
{
int aNum;
public B() :base(100) // base = 부모클래스의 생성자를 지칭 base 없으면 default 생성자 호출
{
aNum = 100; // 메소드의 지역변수
base.aNum = 200; // B 클래스 (자식) 의 인스턴스 변수
this.aNum = 300; // A 클래스 (부모) 의 인스턴스 변수
Console.WriteLine("B 생성자 디폴트");
}
}
class Program
{
static void Main(string[] args)
{
B Obj = new B();
}
}
Sealed : 상속을 못하도록 class 설정 하는 방법
Sealed class Base
{
}
이런식으로 하면 Base 는 상속 불가능 하다.
부모 클래스로 초기화
부모 클래스 객체 참조 변수로 자식 클래스의 주소를 가질 수 있다.
using System;
class 동물
{
}
class 인간 :동물
{
}
class 댕댕이 : 동물
{
}
class Car
{
}
class BMW : Car
{
}
class KIA : Car
{
}
class Program
{
static void Main(string[] args)
{
// 상위 개념은 하위 개념을 포함한다.
// 즉 부모 클래스 객체는 자식 클래스의 생성자로 초기화 가능하다.
동물 동물객체1 = new 동물();
동물 동물객체2 = new 인간();
Car Car1 = new Car();
Car Car2 = new BMW();
Car Car3 = new KIA();
}
}
Object 객체
using System;
class Smart
{
}
class Program
{
static void Main(string[] args)
{
object aObject = new Smart(); // 모든 클래스는 object 클래스를 상속 받았다.
}
static void Main1(string[] args)
{
object num;
int iNum = 100;
num = iNum;
Console.WriteLine(num);
double dNum = 3.14;
num = dNum;
Console.WriteLine(num);
string str = "asdf";
num = str;
Console.WriteLine(num);
}
}
사실 object 객체는 무조건 참조 변수로서 값을 힘 영역에 저장하고 참조 값을 가진다.
만약 object 객체 의 값을 int에 할 당하기 위해서는 힙에 저장되어 있는 값을 가져와서 int 형 변환을 거처서 저장된다.
object a = 100;
int b;
b = a
위의 코드가 힙에 저장된 100 을 int b 에다가 할당하는 코드이다.
실제로는 b = (int)a 이런 식으로 동작한다.
반대로 int 에 있는값을 object 에 넣을 때는 형변환을 꼭 명시 해주어야 한다.
object a
int b = 100
a = (object)b;
오브젝트에 저장하는 것을 박싱 , 오브젝트에 있는 값을 int 와 같은 기본형 (스택에 데이터 저장)
데이터에 저장 하는 것을 언 박싱이라 한다.
상속에서 Method override
부모 자식이 똑같은 함수를 가진다면 자식의 함수를 우선한다.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Car
{
public void ON()
{
Console.WriteLine("부릉~~~~`");
}
}
class BMW:Car
{
public void ON()// 메소드오버라이딩
{
Console.WriteLine("부릉(BMW)~~~~`");
}
}
class KIA :Car
{
public void ON() // 메소드오버라이딩
{
Console.WriteLine("부릉(KIA)~~~~`");
}
}
class Program
{
//기본적으로 객체의 메소드 호출은
//객체 참조 변수의 type 기반으로 호출된다.
static void Main(string[] args)
{
Car aCar = new Car();
KIA aKIA = new KIA();
BMW aBMW = new BMW();
aCar.ON();
aKIA.ON();
aBMW.ON();
// 왼쪽 객체 참조 변수의 type 에 따라
// 오른쪽 객체의 중복 메소드 호출이
// 결정된다.
Car Car1 = new KIA();
Car Car2 = new BMW();
Car1.ON(); // 객체는 KIA 이지만 car 의 ON 이 실행도니다.
Car2.ON();
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
class Car
{
public void ON()
{
Console.WriteLine("부릉~~~~`");
}
}
class BMW:Car
{
public void ON()// 메소드오버라이딩
{
Console.WriteLine("부릉(BMW)~~~~`");
}
}
class KIA :Car
{
public void ON() // 메소드오버라이딩
{
Console.WriteLine("부릉(KIA)~~~~`");
}
}
class Program
{
//기본적으로 객체의 메소드 호출은
//객체 참조 변수의 type 기반으로 호출된다.
static void Main(string[] args)
{
Car aCar = new Car();
KIA aKIA = new KIA();
BMW aBMW = new BMW();
aCar.ON();
aKIA.ON();
aBMW.ON();
// 왼쪽 객체 참조 변수의 type 에 따라
// 오른쪽 객체의 중복 메소드 호출이
// 결정된다.
Car Car1 = new KIA();
Car Car2 = new BMW();
Car1.ON(); // 객체는 KIA 이지만 car 의 ON 이 실행도니다.
Car2.ON();
}
}
'공부,일 > C#' 카테고리의 다른 글
210602 (0) | 2021.06.02 |
---|---|
210525_2 (0) | 2021.05.25 |
210524 (0) | 2021.05.24 |
book class 만들기 (0) | 2021.05.23 |
묵시적 형변환&float에 실수 대입 (0) | 2021.05.12 |
댓글