{"id":5651,"date":"2023-12-30T09:38:21","date_gmt":"2023-12-30T08:38:21","guid":{"rendered":"https:\/\/ekiwi.de\/?p=5651"},"modified":"2023-12-30T09:38:21","modified_gmt":"2023-12-30T08:38:21","slug":"c-virtual-vs-abstract","status":"publish","type":"post","link":"https:\/\/ekiwi.de\/index.php\/5651\/c-virtual-vs-abstract\/","title":{"rendered":"C# virtual vs. abstract"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_83 counter-hierarchy ez-toc-counter ez-toc-grey ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Inhalt<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/ekiwi.de\/index.php\/5651\/c-virtual-vs-abstract\/#Abstrakte_Klassen\" >Abstrakte Klassen<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/ekiwi.de\/index.php\/5651\/c-virtual-vs-abstract\/#Abstrakte_Methoden\" >Abstrakte Methoden<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/ekiwi.de\/index.php\/5651\/c-virtual-vs-abstract\/#Virtuelle_Methoden\" >Virtuelle Methoden<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/ekiwi.de\/index.php\/5651\/c-virtual-vs-abstract\/#Unterschiede_zwischen_abstract_und_virtual_zusammengefasst\" >Unterschiede zwischen abstract und virtual zusammengefasst<\/a><\/li><\/ul><\/nav><\/div>\n<p>Wenn man in C# an mehr oder weniger gro\u00dfen Projekten programmiert, wird man fr\u00fcher oder sp\u00e4ter auf Klassen und Methoden sto\u00dfen, die einen speziellen Modifizierer vorangestellt haben, wie die Modifizierer <em><strong>abstract<\/strong> <\/em>und <em><strong>virtual<\/strong><\/em>. Dabei ist es nicht gleich einleuchtend, worin der Unterschied zwischen <em>abstract<\/em> und <em>virtual<\/em> besteht.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Abstrakte_Klassen\"><\/span>Abstrakte Klassen<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Ein wesentliches Merkmal ist, dass es abstrakte Klassen geben kann, die den Modifizierer abstract vorangestellt haben k\u00f6nnen. Es gibt aber keine virtuellen Klassen. Neben abstract k\u00f6nnen Klassen auch noch die Modifizierer <em>static<\/em>, <em>sealed<\/em> und <em>partial<\/em> vorangestellt haben.<\/p>\n<p>Erstellt man eine abstrakte Klasse, so bestimmt man damit, wie diese sich im Rahmen der Vererbung verh\u00e4lt. Von einer abstrakten Klasse lassen sich keine Instanzen bilden. Die abstrakte Klasse definiert somit nur das Grundger\u00fcst f\u00fcr die zu vererbenden Eigenschaften an eine abgeleitete Klasse.<\/p>\n<p>F\u00fcrs Verst\u00e4ndnis k\u00f6nnte eine solche Klasse zum Beispiel Tier (Animal) hei\u00dfen, welche das Grundger\u00fcst vorgibt und von welcher dann alle weiteren Tierklassen, z.B. Vogel (Bird) abgeleitet werden.<\/p>\n<figure>\n<pre><code><span style=\"color: #3366ff;\">public abstract class<\/span> <span style=\"color: #33cccc;\">Animal<\/span>\r\n{\r\n    <span style=\"color: #3366ff;\">public string<\/span>? Name { <span style=\"color: #3366ff;\">get<\/span>; <span style=\"color: #3366ff;\">set<\/span>; }\r\n    <span style=\"color: #3366ff;\">public int<\/span> Age { <span style=\"color: #3366ff;\">get<\/span>; <span style=\"color: #3366ff;\">set<\/span>; }\r\n    <span style=\"color: #3366ff;\">public abstract void<\/span> <span style=\"color: #993300;\">Eat<\/span>();\r\n    <span style=\"color: #3366ff;\">public abstract void<\/span> <span style=\"color: #993300;\">Sleep<\/span>();\r\n}<\/code><\/pre><figcaption>C# Code-Beispiel abstrakte Klasse<\/figcaption><\/figure>\n<figure>\n<pre><code><span style=\"color: #3366ff;\">public class<\/span> <span style=\"color: #33cccc;\">Bird<\/span>:<span style=\"color: #33cccc;\">Animal<\/span>\r\n{\r\n    <span style=\"color: #3366ff;\">public override void<\/span> <span style=\"color: #993300;\">Eat<\/span>()\r\n    {\r\n        <span style=\"color: #33cccc;\">Debug<\/span>.<span style=\"color: #993300;\">WriteLine<\/span>(<span style=\"color: #ff0000;\">\"Bird Eat\"<\/span>);\r\n    }\r\n\r\n    <span style=\"color: #3366ff;\">public override void<\/span> <span style=\"color: #993300;\">Sleep<\/span>()\r\n    {\r\n        <span style=\"color: #33cccc;\">Debug<\/span>.<span style=\"color: #993300;\">WriteLine<\/span>(<span style=\"color: #ff0000;\">\"Bird Sleep\"<\/span>);\r\n    }\r\n    <span style=\"color: #3366ff;\">public<\/span> <span style=\"color: #33cccc;\">Bird<\/span>()\r\n    {\r\n        Name = <span style=\"color: #ff0000;\">\"Bird\"<\/span>;\r\n        Age = 1;\r\n    }\r\n}<\/code><\/pre><figcaption>C# Code-Beispiel abgeleitete Klasse von abstrakter Klasse<\/figcaption><\/figure>\n<p>Man sieht, innerhalb der Klasse werden auch abstrakte Methoden definiert. Damit es zu keinem Compiler-Fehler kommt, m\u00fcssen in den abgeleiteten Klassen ebenfalls die als abstrakt definierten Methoden implementiert werden. Dadurch haben abstrakte Klassen eine sehr gro\u00dfe \u00c4hnlichkeit mit <a href=\"https:\/\/learn.microsoft.com\/de-de\/dotnet\/csharp\/language-reference\/keywords\/interface\" target=\"_blank\" rel=\"noopener\"><em>Interfaces<\/em><\/a>.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Abstrakte_Methoden\"><\/span>Abstrakte Methoden<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>In dem Code-Beispiel oben haben wir gesehen, dass auch Methoden als <em>abstract<\/em> definiert werden k\u00f6nnen. Solche abstrakten Methoden enthalten keinen Code und m\u00fcssen in der abgeleiteten Klasse \u00fcberschrieben werden mit <em>override<\/em> und implementiert werden. Siehe Code-Beispiel oben, wo wir als Implementierung nur eine Konsolen-Ausgabe mit <em>WriteLine<\/em> machen.<\/p>\n<p>Die abstrakten Methoden sind immer Bestandteil einer abstrakten Klasse.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Virtuelle_Methoden\"><\/span>Virtuelle Methoden<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Den Bezeichner <em>virtual<\/em> setzt man immer dann vor eine Methode, wenn diese von einer abgeleiteten Klasse \u00fcberschrieben werden kann. Der gro\u00dfe Unterschied zu <em>abstract<\/em> ist, dass eine virtuelle Methode implementiert wird, das hei\u00dft also bereits Code enth\u00e4lt. Au\u00dferdem kann eine virtuelle Methode sowohl in abstrakten Klassen als auch in normalen Klassen verwendet werden. Wir verdeutlichlichen dieses Verhalten, in dem wir das Code-Beispiel von oben um die virtuelle Methode <em>Move()<\/em> erweitern.<\/p>\n<figure>\n<pre><code><span style=\"color: #3366ff;\">public abstract class<\/span> <span style=\"color: #33cccc;\">Animal<\/span>\r\n{\r\n    <span style=\"color: #3366ff;\">public string<\/span>? Name { <span style=\"color: #3366ff;\">get<\/span>; <span style=\"color: #3366ff;\">set<\/span>; }\r\n    <span style=\"color: #3366ff;\">public int<\/span> Age { <span style=\"color: #3366ff;\">get<\/span>; <span style=\"color: #3366ff;\">set<\/span>; }\r\n    <span style=\"color: #3366ff;\">public abstract void<\/span> <span style=\"color: #993300;\">Eat<\/span>();\r\n    <span style=\"color: #3366ff;\">public abstract void<\/span> <span style=\"color: #993300;\">Sleep<\/span>();\r\n    <span style=\"color: #3366ff;\">public virtual void<\/span> <span style=\"color: #993300;\">Move<\/span>()\r\n    {\r\n        <span style=\"color: #33cccc;\">Console<\/span>.<span style=\"color: #993300;\">WriteLine<\/span>(<span style=\"color: #ff0000;\">\"Animal Move\"<\/span>);\r\n    }\r\n}<\/code><\/pre><figcaption>C# Code-Beispiel mit virtuelle Methode<\/figcaption><\/figure>\n<figure>\n<pre><code><span style=\"color: #3366ff;\">public class<\/span> <span style=\"color: #33cccc;\">Bird<\/span>:<span style=\"color: #33cccc;\">Animal<\/span>\r\n{\r\n    <span style=\"color: #3366ff;\">public override void<\/span> <span style=\"color: #993300;\">Eat<\/span>()\r\n    {\r\n        <span style=\"color: #33cccc;\">Debug<\/span>.<span style=\"color: #993300;\">WriteLine<\/span>(<span style=\"color: #ff0000;\">\"Bird Eat\"<\/span>);\r\n    }\r\n\r\n    <span style=\"color: #3366ff;\">public override void<\/span> <span style=\"color: #993300;\">Sleep<\/span>()\r\n    {\r\n        <span style=\"color: #33cccc;\">Debug<\/span>.<span style=\"color: #993300;\">WriteLine<\/span>(<span style=\"color: #ff0000;\">\"Bird Sleep\"<\/span>);\r\n    }\r\n    <span style=\"color: #3366ff;\">public<\/span> <span style=\"color: #33cccc;\">Bird<\/span>()\r\n    {\r\n        Name = <span style=\"color: #ff0000;\">\"Bird\"<\/span>;\r\n        Age = 1;\r\n    }\r\n    <span style=\"color: #3366ff;\">public override void<\/span> <span style=\"color: #993300;\">Move<\/span>()\r\n    {\r\n        <span style=\"color: #33cccc;\">Debug<\/span>.<span style=\"color: #993300;\">WriteLine<\/span>(<span style=\"color: #ff0000;\">\"Bird is jumping\"<\/span>);\r\n    }\r\n}<\/code><\/pre><figcaption>C# Code-Beispiel abgeleitete Klasse mit \u00dcberschreibung virtuelle Methode<\/figcaption><\/figure>\n<p>In der abgeleiteten Klasse kann die virtuelle Methode \u00fcberschrieben werden, muss aber nicht \u00fcberschrieben werden.<\/p>\n<h2><span class=\"ez-toc-section\" id=\"Unterschiede_zwischen_abstract_und_virtual_zusammengefasst\"><\/span>Unterschiede zwischen abstract und virtual zusammengefasst<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<ul>\n<li><em>abstract<\/em> kann als Modifizierer f\u00fcr Klassen verwendet werden; <em>virtual<\/em> nicht<\/li>\n<li><em>abstract<\/em> und <em>virtual<\/em> k\u00f6nnen Methoden vorangestellt werden<\/li>\n<li>abstrakte Methoden sind Bestandteil von abstrakten Klassen<\/li>\n<li>virtuelle Methoden k\u00f6nnen Bestandteil von abstrakten und normalen Klassen sein<\/li>\n<li>abstrakte Methoden <strong>enthalten keinen Code<\/strong> und <strong>m\u00fcssen<\/strong> in der abgeleiteten Klasse <strong>\u00fcberschrieben werden<\/strong><\/li>\n<li>virtuelle Methoden enthalten Coden und k\u00f6nnen in abgeleiteten Klassen \u00fcberschrieben werden<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Wenn man in C# an mehr oder weniger gro\u00dfen Projekten programmiert, wird man fr\u00fcher oder sp\u00e4ter auf Klassen und Methoden<\/p>\n","protected":false},"author":2,"featured_media":1011,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[13],"tags":[190,292,1131,136,80,191],"class_list":["post-5651","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programmierung","tag-c","tag-code","tag-coding","tag-programmieren","tag-programmierung","tag-visual-studio"],"_links":{"self":[{"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/posts\/5651","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/comments?post=5651"}],"version-history":[{"count":0,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/posts\/5651\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/media\/1011"}],"wp:attachment":[{"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/media?parent=5651"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/categories?post=5651"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/ekiwi.de\/index.php\/wp-json\/wp\/v2\/tags?post=5651"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}