Bagikan melalui


abstrak (Referensi C#)

Pengubah abstract menunjukkan bahwa targetnya memiliki implementasi yang hilang atau tidak lengkap. Gunakan pengubah abstrak dengan kelas, metode, properti, pengindeks, dan peristiwa. Gunakan pengubah abstract dalam deklarasi kelas untuk menunjukkan bahwa suatu kelas hanya dimaksudkan untuk menjadi kelas dasar bagi kelas lainnya, tidak dibuat dengan sendirinya. Kelas non-abstrak yang berasal dari kelas abstrak harus menerapkan anggota yang ditandai sebagai abstrak.

Referensi bahasa C# mendokumentasikan versi bahasa C# yang paling baru dirilis. Ini juga berisi dokumentasi awal untuk fitur dalam pratinjau publik untuk rilis bahasa yang akan datang.

Dokumentasi mengidentifikasi fitur apa pun yang pertama kali diperkenalkan dalam tiga versi terakhir bahasa atau dalam pratinjau publik saat ini.

Petunjuk / Saran

Untuk menemukan kapan fitur pertama kali diperkenalkan di C#, lihat artikel tentang riwayat versi bahasa C#.

Kelas abstrak dapat berisi anggota abstrak (yang tidak memiliki implementasi dan harus ditimpa dalam kelas turunan) dan anggota yang sepenuhnya diimplementasikan (seperti metode reguler, properti, dan konstruktor). Fitur ini memungkinkan kelas abstrak untuk menyediakan fungsionalitas umum sambil tetap memerlukan kelas turunan untuk menerapkan anggota abstrak tertentu.

Nota

Anggota antarmuka secara abstract default.

Kelas abstrak dengan anggota campuran

Contoh berikut menunjukkan kelas abstrak yang berisi metode yang diimplementasikan dan anggota abstrak:

namespace LanguageKeywords;

public abstract class Vehicle
{
    protected string _brand;
    
    // Constructor - implemented method in abstract class
    public Vehicle(string brand) => _brand = brand;
    
    // Implemented method - provides functionality that all vehicles share
    public string GetInfo() => $"This is a {_brand} vehicle.";
    
    // Another implemented method
    public virtual void StartEngine() => Console.WriteLine($"{_brand} engine is starting...");
    
    // Abstract method - must be implemented by derived classes
    public abstract void Move();
    
    // Abstract property - must be implemented by derived classes  
    public abstract int MaxSpeed { get; }
}

public class Car : Vehicle
{
    public Car(string brand) : base(brand) { }
    
    // Implementation of abstract method
    public override void Move() => Console.WriteLine($"{_brand} car is driving on the road.");
    
    // Implementation of abstract property
    public override int MaxSpeed => 200;
}

public class Boat : Vehicle
{
    public Boat(string brand) : base(brand) { }
    
    // Implementation of abstract method
    public override void Move() => Console.WriteLine($"{_brand} boat is sailing on the water.");
    
    // Implementation of abstract property
    public override int MaxSpeed => 50;
}

public class AbstractExample
{
    public static void Examples()
    {
        // Cannot instantiate abstract class: Vehicle v = new Vehicle("Generic"); // Error!
        
        Car car = new Car("Toyota");
        Boat boat = new Boat("Yamaha");
        
        // Using implemented methods from abstract class
        Console.WriteLine(car.GetInfo());
        car.StartEngine();
        
        // Using abstract methods implemented in derived class
        car.Move();
        Console.WriteLine($"Max speed: {car.MaxSpeed} km/h");
        
        Console.WriteLine();
        
        Console.WriteLine(boat.GetInfo());
        boat.StartEngine();
        boat.Move();
        Console.WriteLine($"Max speed: {boat.MaxSpeed} km/h");
    }
}

class Program
{
    static void Main()
    {
        AbstractExample.Examples();
    }
}
/* Output:
This is a Toyota vehicle.
Toyota engine is starting...
Toyota car is driving on the road.
Max speed: 200 km/h

This is a Yamaha vehicle.
Yamaha engine is starting...
Yamaha boat is sailing on the water.
Max speed: 50 km/h
*/

Dalam contoh ini, Vehicle kelas abstrak menyediakan:

  • Anggota yang diimplementasikan: GetInfo() metode, StartEngine() metode, dan konstruktor - anggota ini menyediakan fungsionalitas umum untuk semua kendaraan.
  • Anggota abstrak: Move() metode dan MaxSpeed properti - anggota ini harus diimplementasikan oleh setiap jenis kendaraan tertentu.

Desain ini memungkinkan kelas abstrak untuk menyediakan fungsionalitas bersama sambil memastikan bahwa kelas turunan menerapkan perilaku khusus kendaraan.

Kelas beton berasal dari kelas abstrak

Dalam contoh ini, kelas Square harus menyediakan implementasi GetArea karena berasal dari Shape:

abstract class Shape
{
    public abstract int GetArea();
}

class Square : Shape
{
    private int _side;

    public Square(int n) => _side = n;

    // GetArea method is required to avoid a compile-time error.
    public override int GetArea() => _side * _side;

    static void Main()
    {
        var sq = new Square(12);
        Console.WriteLine($"Area of the square = {sq.GetArea()}");
    }
}
// Output: Area of the square = 144

Kelas abstrak memiliki fitur sebagai berikut:

  • Anda tidak dapat membuat instans kelas abstrak.
  • Kelas abstrak dapat berisi metode abstrak dan aksesor.
  • Kelas abstrak juga dapat berisi metode, properti, bidang, dan anggota lain yang diimplementasikan yang menyediakan fungsionalitas untuk kelas turunan.
  • Anda tidak dapat menggunakan pengubah sealed pada kelas abstrak karena kedua pengubah memiliki arti yang berlawanan. Pengubah sealed mencegah kelas diwariskan dan pengubah abstract mengharuskan kelas untuk diwariskan.
  • Kelas non-abstrak yang berasal dari kelas abstrak harus mencakup implementasi aktual dari semua metode dan pengakses abstrak yang diwariskan.

Gunakan pengubah abstract dalam metode atau deklarasi properti untuk menunjukkan bahwa metode atau properti tidak berisi implementasi.

Metode abstrak memiliki fitur sebagai berikut:

  • Metode abstrak secara implisit merupakan metode virtual.

  • Deklarasi metode abstrak hanya diizinkan dalam kelas abstrak.

  • Karena deklarasi metode abstrak tidak menyediakan implementasi aktual, tidak ada isi metode. Deklarasi metode hanya berakhir dengan titik koma. Contohnya:

    public abstract void MyMethod();
    

    Implementasi disediakan oleh metode override, yang merupakan anggota kelas non-abstrak.

  • Ini adalah kesalahan untuk menggunakan static pengubah atau virtual dalam deklarasi metode abstrak dalam jenis class . Anda dapat mendeklarasikan static abstract dan static virtual metode dalam antarmuka.

    Properti abstrak berperilaku seperti metode abstrak, kecuali untuk perbedaan sintaksis deklarasi dan pemanggilan.

  • Ini adalah kesalahan untuk menggunakan pengubah abstract pada properti statis dalam satu class jenis. Anda dapat mendeklarasikan static abstract atau static virtual properti dalam deklarasi antarmuka.

  • Properti abstrak yang diwariskan dapat ditimpa di kelas turunan dengan menyertakan deklarasi properti yang menggunakan pengubah override .

Untuk informasi selengkapnya tentang kelas abstrak, lihat Kelas Abstrak dan Tersegel serta Anggota Kelas.

Kelas abstrak harus menyediakan implementasi untuk semua anggota antarmuka. Kelas abstrak yang mengimplementasikan antarmuka dapat memetakan metode antarmuka ke metode abstrak. Contohnya:

interface I
{
    void M();
}

abstract class C : I
{
    public abstract void M();
}

Dalam contoh berikut, kelas DerivedClass berasal dari kelas BaseClassabstrak . Kelas abstrak berisi metode abstrak, AbstractMethod, dan dua properti abstrak, X dan Y.

// Abstract class
abstract class BaseClass
{
    protected int _x = 100;
    protected int _y = 150;

    // Abstract method
    public abstract void AbstractMethod();

    // Abstract properties
    public abstract int X { get; }
    public abstract int Y { get; }
}

class DerivedClass : BaseClass
{
    public override void AbstractMethod()
    {
        _x++;
        _y++;
    }

    public override int X   // overriding property
    {
        get
        {
            return _x + 10;
        }
    }

    public override int Y   // overriding property
    {
        get
        {
            return _y + 10;
        }
    }

    static void Main()
    {
        var o = new DerivedClass();
        o.AbstractMethod();
        Console.WriteLine($"x = {o.X}, y = {o.Y}");
    }
}
// Output: x = 111, y = 161

Dalam contoh sebelumnya, jika Anda mencoba untuk mewakilkan kelas abstrak menggunakan pernyataan seperti ini:

BaseClass bc = new BaseClass();   // Error

Anda mendapatkan kesalahan yang mengatakan bahwa pengkompilasi tidak dapat membuat instans kelas abstrak 'BaseClass'. Namun, Anda dapat menggunakan konstruktor kelas abstrak, seperti yang ditunjukkan dalam contoh berikut.

public abstract class Shape
{
    public string Color { get; set; }

    // Constructor of the abstract class
    protected Shape(string color)
    {
        Color = color;
        Console.WriteLine($"Created a shape with color {color}.");
    }

    // Abstract method that must be implemented by derived classes
    public abstract double CalculateArea();
}

public class Square : Shape
{
    public double Side { get; set; }

    // Constructor of the derived class calling the base class constructor
    public Square(string color, double side) : base(color)
    {
        Side = side;
    }

    public override double CalculateArea()
    {
        return Side * Side;
    }
}

public class Program
{
    public static void Main(string[] args)
     {
            Square square = new Square("red", 5);
            Console.WriteLine($"Area of the square: {square.CalculateArea()}");            
     }
}

Kelas Shape dinyatakan abstract, yang berarti Anda tidak dapat membuat instans secara langsung. Sebaliknya, ini berfungsi sebagai cetak biru untuk kelas lain.

  • Meskipun Anda tidak dapat membuat objek dari kelas abstrak, objek tersebut masih dapat memiliki konstruktor. Konstruktor ini biasanya protected, yang berarti hanya kelas turunan yang dapat mengaksesnya. Dalam hal ini, konstruktor Shape mengambil parameter color dan menginisialisasi properti Color. Ini juga mencetak pesan ke konsol. Bagian public Square(string color, double side) : base(color) memanggil konstruktor kelas dasar (Shape) dan meneruskan argumen color ke dalamnya.
  • Shape Di kelas , konstruktor yang ditentukan mengambil warna sebagai parameter protected Shape(string color). Ini berarti C# tidak lagi menyediakan konstruktor tanpa parameter default secara otomatis. Kelas turunan harus menggunakan : base(color) ekspresi untuk memanggil konstruktor dasar. Mengatur nilai default ke warna protected Shape(string color="green") memungkinkan menghilangkan : base(color) ekspresi di kelas turunan. Konstruktor protected Shape(string color="green") mengatur warna menjadi hijau.

Spesifikasi Bahasa C#

Untuk informasi selengkapnya, lihat Spesifikasi Bahasa C#. Spesifikasi bahasa adalah sumber definitif untuk sintaks dan penggunaan C#.

Lihat juga