{"id":463,"date":"2023-04-01T20:33:32","date_gmt":"2023-04-01T13:33:32","guid":{"rendered":"https:\/\/csharptutorial.net\/?page_id=463"},"modified":"2023-04-01T21:13:11","modified_gmt":"2023-04-01T14:13:11","slug":"csharp-abstract-class-and-interface","status":"publish","type":"page","link":"https:\/\/www.csharptutorial.net\/csharp-tutorial\/csharp-abstract-class-and-interface\/","title":{"rendered":"C# Abstract Class and Interface"},"content":{"rendered":"\n<p><strong>Summary<\/strong>: in this tutorial, you&#8217;ll learn when to use an abstract class and when to use an interface and the differences between an abstract class and an interface. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Choosing between an abstract class and an interface<\/h2>\n\n\n\n<p>In C#, an <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-abstract-class\/\">abstract class<\/a> is similar to an <a href=\"https:\/\/csharptutorial.net\/csharp-tutorial\/csharp-interface\/\">interface<\/a>. However, the abstract class and interface serve different purposes. Therefore, it&#8217;s important to know when to use an abstract class and when to use an interface.<\/p>\n\n\n\n<p>Generally, when you want to model the is-a relationship and share a common implementation with all the subclasses, you use an abstract class. <\/p>\n\n\n\n<p>But when you want to create a contract that other classes must adhere to, you use an interface. <\/p>\n\n\n\n<p>The following example demonstrates how to use the abstract class Shape that has the Display() method shared by all of its subclasses:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Shape<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">GetArea<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>;\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">abstract<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">GetPerimeter<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Display<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n    {\n        Console.WriteLine(<span class=\"hljs-string\">$\"Area: <span class=\"hljs-subst\">{GetArea():F2}<\/span>, Perimeter: <span class=\"hljs-subst\">{GetPerimeter():F2}<\/span>\"<\/span>);\n    }\n}\n\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Rectangle<\/span> : <span class=\"hljs-title\">Shape<\/span>\n{\n    <span class=\"hljs-keyword\">readonly<\/span> <span class=\"hljs-keyword\">double<\/span> length;\n    <span class=\"hljs-keyword\">readonly<\/span> <span class=\"hljs-keyword\">double<\/span> width;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Rectangle<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">double<\/span> length, <span class=\"hljs-keyword\">double<\/span> width<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">this<\/span>.length = length;\n        <span class=\"hljs-keyword\">this<\/span>.width = width;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">GetArea<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">return<\/span> length * width;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">GetPerimeter<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">2<\/span> * (length + width);\n    }\n}\n\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Circle<\/span> : <span class=\"hljs-title\">Shape<\/span>\n{\n    <span class=\"hljs-keyword\">readonly<\/span> <span class=\"hljs-keyword\">double<\/span> radius;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">Circle<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">double<\/span> radius<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">this<\/span>.radius = radius;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">GetArea<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">return<\/span> Math.PI * radius * radius;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">override<\/span> <span class=\"hljs-keyword\">double<\/span> <span class=\"hljs-title\">GetPerimeter<\/span>(<span class=\"hljs-params\"><\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-number\">2<\/span> * Math.PI * radius;\n    }\n}\n\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Program<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Main<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span>&#91;] args<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">var<\/span> shapes = <span class=\"hljs-keyword\">new<\/span> List&lt;Shape&gt;()\n        {\n            <span class=\"hljs-keyword\">new<\/span> Rectangle(<span class=\"hljs-number\">5<\/span>, <span class=\"hljs-number\">10<\/span>),\n            <span class=\"hljs-keyword\">new<\/span> Circle(<span class=\"hljs-number\">3<\/span>)\n        };\n\n        <span class=\"hljs-keyword\">foreach<\/span> (<span class=\"hljs-keyword\">var<\/span> shape <span class=\"hljs-keyword\">in<\/span> shapes)\n        {\n            shape.Display();\n        }\n\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>Output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">Area<\/span>: 50<span class=\"hljs-selector-class\">.00<\/span>, <span class=\"hljs-selector-tag\">Perimeter<\/span>: 30<span class=\"hljs-selector-class\">.00<\/span>\n<span class=\"hljs-selector-tag\">Area<\/span>: 28<span class=\"hljs-selector-class\">.27<\/span>, <span class=\"hljs-selector-tag\">Perimeter<\/span>: 18<span class=\"hljs-selector-class\">.85<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this example, the <code>Shape<\/code>  class is an abstract class that defines two abstract methods <code>GetArea<\/code> and <code>GetPerimeter<\/code>. Any class that inherits from the Shape class needs to implement these methods. <\/p>\n\n\n\n<p>The <code>Shape<\/code> class also has a concrete method <code>Display<\/code> that displays the area and perimeter of a shape. All the subclasses of the <code>Shape<\/code> class will share the same <code>Display<\/code> method.<\/p>\n\n\n\n<p>The Rectangle and Circle classes extend the Shape class. Both of these classes share the same implementation of <code>Display<\/code> method, but they each provide their own implementation of <code>GetArea<\/code> and <code>GetPerimeter<\/code> methods.<\/p>\n\n\n\n<p>The following example demonstrates how to use an interface as a contract:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"C#\" data-shcb-language-slug=\"cs\"><span><code class=\"hljs language-cs\"><span class=\"hljs-keyword\">interface<\/span> <span class=\"hljs-title\">ILogger<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Log<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> message<\/span>)<\/span>;\n}\n\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">ConsoleLogger<\/span> : <span class=\"hljs-title\">ILogger<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Log<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> message<\/span>)<\/span>\n    {\n        Console.WriteLine(message);\n    }\n}\n\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">FileLogger<\/span> : <span class=\"hljs-title\">ILogger<\/span>\n{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">readonly<\/span> <span class=\"hljs-keyword\">string<\/span> filePath;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">FileLogger<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> filePath<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">this<\/span>.filePath = filePath;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Log<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span> message<\/span>)<\/span>\n    {\n        <span class=\"hljs-keyword\">using<\/span> StreamWriter writer = <span class=\"hljs-keyword\">new<\/span> StreamWriter(filePath, <span class=\"hljs-literal\">true<\/span>);\n        writer.WriteLine(message);\n    }\n}\n\n<span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">Program<\/span>\n{\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">static<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">Main<\/span>(<span class=\"hljs-params\"><span class=\"hljs-keyword\">string<\/span>&#91;] args<\/span>)<\/span>\n    {\n        ILogger logger;\n\n        <span class=\"hljs-keyword\">if<\/span> (args.Length &gt; <span class=\"hljs-number\">0<\/span> &amp;&amp; args&#91;<span class=\"hljs-number\">0<\/span>] == <span class=\"hljs-string\">\"file\"<\/span>)\n        {\n            logger = <span class=\"hljs-keyword\">new<\/span> FileLogger(<span class=\"hljs-string\">\"log.txt\"<\/span>);\n        }\n        <span class=\"hljs-keyword\">else<\/span>\n        {\n            logger = <span class=\"hljs-keyword\">new<\/span> ConsoleLogger();\n        }\n\n        logger.Log(<span class=\"hljs-string\">\"Starting application...\"<\/span>);\n\n        <span class=\"hljs-comment\">\/\/ ... <\/span>\n\n        logger.Log(<span class=\"hljs-string\">\"Application stopped.\"<\/span>);\n    }\n}\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">C#<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">cs<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p>In this example, we define the <code>ILogger<\/code> interface that has a single method <code>Log<\/code>. The <code>Log<\/code> method takes a string that represents the message to be logged.<\/p>\n\n\n\n<p>The <code>ConsoleLogger<\/code> and <code>FileLogger<\/code> classes implement the <code>ILogger<\/code> interface and provide their own implementations of the <code>Log<\/code> method.<\/p>\n\n\n\n<p>In the <code>Main<\/code> method, we create an instance of <code>ConsoleLogger<\/code> or <code>FileLogger<\/code> based on the command line argument.<\/p>\n\n\n\n<p>If the argument is <code>\"file\"<\/code>, we create a <code>FileLogger<\/code> object. Otherwise, we create a <code>ConsoleLogger<\/code> object.<\/p>\n\n\n\n<p>Regardless of whether <code>FileLogger<\/code> or <code>ConsoleLogger<\/code> instance was created, we call the <code>Log<\/code> method to log some messages<\/p>\n\n\n\n<p>Since both <code>FileLogger<\/code> and <code>ConsoleLogger<\/code> classes implement the same interface, we can easily switch between them at runtime.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Abstract class vs. Interface<\/h2>\n\n\n\n<p>The following table illustrates the differences between abstract classes and interfaces:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><thead><tr><th>Abstract Classes<\/th><th>Interfaces<\/th><\/tr><\/thead><tbody><tr><td>Shared implementation<\/td><td>Define a contract<\/td><\/tr><tr><td>Can only inherit from a single base class<\/td><td>Can implement any number of interfaces<\/td><\/tr><tr><td>Unconstrainted implementation code<\/td><td>Limited implementation code<\/td><\/tr><tr><td>Can have automatic properties<\/td><td>No automatic properties<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Use an abstract class to model an is-a relationship and share a common implementation with all subclasses.<\/li>\n\n\n\n<li>Use an interface to represent a contract to which other classes must adhere.<\/li>\n<\/ul>\n<div class=\"helpful-block-content\" data-title=\"\">\n\t<header>\n\t\t<div class=\"wth-question\">Was this tutorial helpful ?<\/div>\n\t\t<div class=\"wth-thumbs\">\n\t\t\t<button\n\t\t\t\tdata-post=\"463\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-tutorial\/csharp-abstract-class-and-interface\/\"\n\t\t\t\tdata-post-title=\"C# Abstract Class and Interface\"\n\t\t\t\tdata-response=\"1\"\n\t\t\t\tclass=\"wth-btn-rounded wth-yes-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t\tclass=\"feather feather-thumbs-up block w-full h-full\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M14 9V5a3 3 0 0 0-3-3l-4 9v11h11.28a2 2 0 0 0 2-1.7l1.38-9a2 2 0 0 0-2-2.3zM7 22H4a2 2 0 0 1-2-2v-7a2 2 0 0 1 2-2h3\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> Yes <\/span>\n\t\t\t<\/button>\n\n\t\t\t<button\n\t\t\t\tdata-response=\"0\"\n\t\t\t\tdata-post=\"463\"\n\t\t\t\tdata-post-url=\"https:\/\/www.csharptutorial.net\/csharp-tutorial\/csharp-abstract-class-and-interface\/\"\n\t\t\t\tdata-post-title=\"C# Abstract Class and Interface\"\n\t\t\t\tclass=\"wth-btn-rounded wth-no-btn\"\n\t\t\t>\n\t\t\t\t<svg\n\t\t\t\t\txmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n\t\t\t\t\tviewBox=\"0 0 24 24\"\n\t\t\t\t\tfill=\"none\"\n\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\tstroke-linecap=\"round\"\n\t\t\t\t\tstroke-linejoin=\"round\"\n\t\t\t\t>\n\t\t\t\t\t<path\n\t\t\t\t\t\td=\"M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17\"\n\t\t\t\t\t><\/path>\n\t\t\t\t<\/svg>\n\t\t\t\t<span class=\"sr-only\"> No <\/span>\n\t\t\t<\/button>\n\t\t<\/div>\n\t<\/header>\n\n\t<div class=\"wth-form hidden\">\n\t\t<div class=\"wth-form-wrapper\">\n\t\t\t<div class=\"wth-title\"><\/div>\n\t\t\t\n\t\t\t<textarea class=\"wth-message\"><\/textarea>\n\n\t\t\t<button class=\"btn btn-primary wth-btn-submit\">Send<\/button>\n\t\t\t<button class=\"btn wth-btn-cancel\">Cancel<\/button>\n\t\t\n\t\t<\/div>\n\t<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In this tutorial, you&#8217;ll learn when to use an abstract class and when to use an interface in C# and the differences between them.<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":7,"menu_order":54,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-463","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/463","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/comments?post=463"}],"version-history":[{"count":5,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/463\/revisions"}],"predecessor-version":[{"id":1337,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/463\/revisions\/1337"}],"up":[{"embeddable":true,"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/pages\/7"}],"wp:attachment":[{"href":"https:\/\/www.csharptutorial.net\/wp-json\/wp\/v2\/media?parent=463"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}