Klass - in objektorienterad programmering , en modell för att skapa objekt av en viss typ , som beskriver deras struktur (en uppsättning fält och deras initiala tillstånd) och definierar algoritmer (funktioner eller metoder ) för att arbeta med dessa objekt.
Med andra ord, en klass fungerar som ett medel för att introducera abstrakta datatyper i ett mjukvaruprojekt. Andra deskriptorer av abstrakta datatyper - metaklasser , gränssnitt , strukturer , uppräkningar - kännetecknas av några av sina egna egenskaper. Kärnan i skillnaden mellan klasser är att när en datatyp specificeras, definierar en klass samtidigt både ett gränssnitt och en implementering för alla dess instanser (dvs objekt), så att anropa konstruktormetoden är obligatoriskt.
Klassen är ett av nyckelbegreppen i OOP , men det finns också klasslösa objektorienterade språk, som Self , JavaScript , Lua , (se Prototypprogrammering för mer information ).
I praktiken handlar objektorienterad programmering om att skapa ett antal klasser, inklusive ett gränssnitt och en implementering, och sedan använda dem. En grafisk representation av ett antal klasser och relationerna mellan dem kallas ett klassdiagram . Under utvecklingen har det objektorienterade tillvägagångssättet samlat på sig många rekommendationer ( mönster ) för att skapa klasser och klasshierarkier .
Idén med klasser kom från kunskapsbasarbete som är relevant för forskning om artificiell intelligens. Klassificeringarna som används av människan inom zoologi, botanik, kemi, maskindelar bär grundtanken att vilken sak som helst alltid kan representeras som ett specialfall av något mer allmänt begrepp. Ett speciellt äpple är ett äpple i allmänhet, ett äpple i allmänhet, och vilket äpple som helst är en frukt. (Äpplen och päron är ett vanligt exempel på klasser i objektorienterade programmeringshandledningar.)
Överallt nedan kommer orden "klass", " objekt ", " gränssnitt " och " struktur " att användas i deras speciella betydelser som ges inom OOP.
I ett objektorienterat program som använder klasser är varje objekt en " instans " av en viss klass, och inga andra objekt tillhandahålls. Det vill säga, "en instans av en klass " betyder i det här fallet inte "ett exempel på någon klass" eller "en enda klass", utan "ett objekt vars typ är någon klass." Samtidigt, i olika programmeringsspråk, är förekomsten av vissa andra datatyper tillåten eller inte tillåten, vars instanser inte är objekt (det vill säga språket avgör om sådana saker som siffror, arrayer och pekare är objekt, eller inte, och följaktligen om det finns klasser som "nummer", "matris" eller "pekare" av vilka varje särskilt nummer, matris eller pekare skulle vara en instans).
Till exempel kan den abstrakta datatypen "textrad" utformas som en klass, och då kommer alla textrader i programmet att vara objekt - instanser av klassen "textrad".
När du använder klasser kan alla element i programkoden, såsom variabler, konstanter, metoder, procedurer och funktioner, tillhöra (och måste på många språk tillhöra) en eller annan klass. Själva klassen definieras i slutändan som en lista över dess medlemmar , nämligen fält ( egenskaper ) och metoder/funktioner/procedurer . Beroende på programmeringsspråket kan konstanter, attribut och externa definitioner läggas till i denna lista.
Precis som strukturer kan klasser definiera fält – det vill säga variabler som hör antingen direkt till själva klassen (statisk) eller till instanser av klassen (vanliga). Statiska fält finns i en instans för hela programmet (eller, i en mer komplex version, i en instans per process eller per tråd/tråd ). Vanliga fält skapas en kopia för varje specifikt objekt - en instans av klassen. Till exempel kommer det totala antalet textrader som skapas i programmet under dess drift att vara ett statiskt fält i klassen "textrad". Och en specifik uppsättning tecken i en sträng kommer att vara ett vanligt fält för en instans av klassen "textsträng", precis som variabeln "efternamn" av typen "textsträng" kommer att vara ett vanligt fält för varje specifik instans av klassen "person".
I OOP, när du använder klasser, kommer all körbar programkod (algoritmer) att presenteras i form av så kallade "metoder", "funktioner" eller "procedurer", vilket motsvarar konventionell strukturerad programmering , men nu kan de (och i många språk måste) tillhöra en eller annan klass. Till exempel, om möjligt, kommer klassen "textsträng" att innehålla alla grundläggande metoder/funktioner/procedurer som är utformade för att arbeta med en textsträng, som att söka i en sträng, klippa en del av en sträng, etc.
Liksom fält kan kod i form av metoder/funktioner/procedurer som hör till en klass hänvisas antingen till själva klassen eller till instanser av klassen. En metod som tillhör en klass och associerad med klassen (statisk metod) kan anropas av sig själv och har tillgång till klassens statiska variabler. En metod associerad med en klassinstans (vanlig metod) kan endast anropas på själva objektet och har tillgång till både de statiska fälten i klassen och de vanliga fälten för ett specifikt objekt (när det anropas kommer detta objekt att skickas som en dold metodparameter). Till exempel kan det totala antalet skapade strängar hittas var som helst i programmet, men längden på en viss sträng kan bara hittas genom att på ett eller annat sätt specificera längden på vilken sträng vi ska mäta.
Inom programmering finns begreppet programmeringsgränssnitt, vilket innebär en lista över möjliga beräkningar som en eller annan del av programmet kan utföra. Detta inkluderar en beskrivning: vilka argument och i vilken ordning som krävs för att skickas till ingången av algoritmerna från listan, samt vilka och i vilken form de kommer att returnera. Gränssnittet för abstrakt datatyp uppfanns för den formaliserade beskrivningen av en sådan lista. Algoritmerna själva, det vill säga den faktiska programkoden som kommer att utföra alla dessa beräkningar, specificeras inte av gränssnittet, de programmeras separat och kallas implementeringen av gränssnittet .
Programmeringsgränssnitt, såväl som klasser, kan utökas genom arv , vilket är ett av de viktiga sätten för kodåteranvändning i OOP. En ärvd klass eller gränssnitt kommer att innehålla allt som är specificerat för alla dess överordnade klasser (beroende på programmeringsspråk och plattform kan det finnas från noll till oändligt). Till exempel kan du skapa din egen version av en textsträng genom att ärva klassen "min textsträng" från den redan befintliga klassen "textsträng", medan det antas att programmeraren inte behöver skriva om sökalgoritmer och så vidare, eftersom de automatiskt kommer att ärvas från den färdiga klassen, och alla förekomster av klassen "min textrad" kan skickas inte bara till färdiga metoder för moderklassen "textrad" för att utföra de nödvändiga beräkningarna, utan i generellt för alla algoritmer som kan fungera med objekt av typen "textrad", eftersom instanser av båda klasserna är gränssnittskompatibla.
Klassen låter dig ställa in inte bara programmeringsgränssnittet till sig själv och till dess instanser, utan också uttryckligen skriva koden som är ansvarig för beräkningarna. Om vi, när vi skapar vår nya datatyp, ärver gränssnittet, kommer vi att kunna skicka en instans av vår datatyp till vilken algoritm som helst som kan fungera med detta gränssnitt. Vi måste dock själva skriva implementeringen av gränssnittet, det vill säga de algoritmer som algoritmen av intresse för oss kommer att använda för att utföra beräkningar med vår instans. Samtidigt, genom att ärva en klass, ärver vi automatiskt den färdiga koden för gränssnittet (detta är inte alltid fallet, förälderklassen kan kräva implementering av vissa algoritmer i den underordnade klassen utan att misslyckas). Denna förmåga att ärva från kod är det som gör det tydligt att i ett objektorienterat program definierar datatypen för en klass både ett gränssnitt och en implementering för alla dess instanser.
Ett av problemen med strukturerad programmering som OOP brottas med är problemet med att bibehålla det korrekta värdet på programvariabler. Ofta lagrar olika programvariabler logiskt relaterade värden, och programmeraren är ansvarig för att upprätthålla denna logiska anslutning, det vill säga anslutningen upprätthålls inte automatiskt. Ett exempel är flaggorna "avskedade" och "förväntar sig en bonus i slutet av året", när en person, enligt personalavdelningens regler, samtidigt inte kan sparkas och inte förväntar sig en bonus, inte sparkas och väntar på en bonus, avskedad och inte förväntar sig en bonus, men kan inte både sparkas och väntar på en bonus. Det vill säga, alla delar av programmet som markerar rutan "avfyrade" ska alltid avmarkera rutan "väntar på årsslutsbonusar".
Ett bra sätt att lösa detta problem är att göra den "avfyrade" flaggan oföränderlig för alla delar av programmet, förutom en specifikt specificerad. I det här specifika avsnittet kommer allt att skrivas en gång och korrekt, och alla andra måste hänvisa till det här avsnittet när de vill markera eller avmarkera rutan "avfyrade".
I ett objektorienterat program kommer den "avfyrade" flaggan att förklaras som en privat medlem av någon klass, och motsvarande offentliga metoder kommer att skrivas för att läsa och ändra den. Reglerna som bestämmer möjligheten eller omöjligheten att direkt ändra några variabler kallas reglerna för att ställa in åtkomstomfång. Orden "privat" och "offentlig" är i detta fall de så kallade " åtkomstmodifierarna ". De kallas modifierare eftersom de på vissa språk används för att ändra tidigare inställda behörigheter när en klass ärvs. Tillsammans definierar klasser och åtkomstmodifierare ett åtkomstområde, det vill säga att varje kodavsnitt, beroende på vilken klass den tillhör, kommer att ha sitt eget åtkomstområde med avseende på vissa element (medlemmar) i dess klass och andra klasser, inklusive variabler , metoder, funktioner , konstanter, etc. Det finns en grundläggande regel: ingenting i en klass kan se de privata medlemmarna i en annan klass. I förhållande till andra, mer komplexa regler, har olika språk olika åtkomstmodifierare och regler för hur de interagerar med klasser.
Nästan varje klassmedlem kan ställas in som en åtkomstmodifierare (med undantag för statiska konstruktorer och några andra saker). De flesta objektorienterade programmeringsspråk stöder följande åtkomstmodifierare:
Problemet med att bibehålla det korrekta tillståndet för variablerna är också relevant för det allra första ögonblicket för inställning av initialvärdena. För att göra detta tillhandahåller klasser speciella metoder/funktioner som kallas konstruktörer. Inget objekt (instans av en klass) kan skapas på annat sätt än genom att anropa konstruktorns kod för exekvering, vilket kommer att returnera till anroparen en skapad och korrekt ifylld instans av klassen. I många programmeringsspråk kan datatypen "struct", som en klass, innehålla variabler och metoder, men instanser av strukturer, som bara förblir ett markerat område av RAM, kan skapas förbi konstruktörer, vilket är förbjudet för klassinstanser ( med undantag för speciella exceptionella metoder för att kringgå alla liknande OOP-regler som finns på vissa språk och plattformar). Detta visar skillnaden mellan klasser och andra datatyper - ett konstruktoranrop krävs.
I moderna objektorienterade programmeringsspråk (inklusive php , Java , C++ , Oberon , Python , Ruby , Smalltalk , Object Pascal ) handlar det om att skapa en klass att skriva en struktur som innehåller en uppsättning fält och metoder (bland de senare, konstruktörer spelar en speciell roll, förstörare, finalister). I praktiken kan en klass förstås som en mall enligt vilken objekt skapas - instanser av denna klass. Alla instanser av samma klass skapas enligt samma mall, så de har samma uppsättning fält och metoder.
Omfattningen av klassmedlemmar (det vill säga omfattningen av koden från vilken de kan nås med ett okvalificerat namn - utan att ange namnet på klassen eller objektet) beror inte på deras omfattning, och är alltid densamma som koden för klassmetoder.
Omfattningen av själva klassen definieras olika i olika programmeringsspråk. I vissa språk (som Delphi ) har alla klasser global synlighet (med hänsyn till modulens synlighet ), i andra (som Java ) är omfattningen av en klass associerad med kompileringsenheten som innehåller den (i Java) - med ett paket ), i andra (som C ++ och C# ), bestäms omfattningen av en klass av namnutrymmen ( namnutrymmen ), som uttryckligen ställs in av programmeraren och kanske matchar kompileringsenheter eller inte.
I Delphi beskrivs klassen enligt följande:
TMyClass = class ( TObject ) private {Delarna som beskrivs i detta avsnitt är inte tillgängliga utifrån (utanför klassen, men tillgängliga inom modulen).} {Klassfält finns vanligtvis här.} strikt privat {För Delphi 2007 och högre. Element som beskrivs i detta avsnitt är endast tillgängliga inom klassen} skyddade {Element som beskrivs i detta avsnitt är endast tillgängliga för klassen och alla dess avkomlingar.} offentliga {Element som beskrivs i detta avsnitt är tillgängliga för alla.} publicerade {Element som beskrivs i detta avsnitt är tillgängliga för alla och visas i Object Inspector'e.} end ;En instans (objekt) av klassen skapas så här:
MyClass := TMyClass . skapa ;Förstört så här:
FreeAndNil ( MyClass ) ; ELLER MyClass . Gratis ;En klass i C++ skapas så här:
class MyClass : public ParentClass // ParentClass - ancestor class, if any { offentliga : // element i detta avsnitt är tillgängliga från alla delar av programmet MyClass (); // konstruktör ~ MyClass (); // destruktor skyddad : // element i det här avsnittet är tillgängliga från klassen och dess avkomlingar privat : // element i detta avsnitt är endast tillgängliga från klassen; detta är standardomfånget };När en klass väl har skapats anses den vara en fullvärdig datatyp och därför skapas instanser av klassen enligt följande:
MyClass mininstans ;Ringa klassmedlemmar:
min instans . klassmedlemEn instans av klassen förstörs, som vilken variabel som helst, endast om funktionen där den skapades har slutfört sitt arbete eller om det dynamiska minnet som tilldelats för klassen har tvångsfrigjorts .
Klasser i C# definieras enligt följande:
public class MyClass { //Medlem tillgänglig för alla klasser i programmet public int k ; //Medlem tillgänglig för alla klasser i samma programmodul intern int l ; //Medlem tillgänglig för vilken klass som helst i samma programmodul, eller endast för den aktuella klassen och alla dess underklasser i en annan modul skyddad intern int m ; //Medlem endast tillgänglig för den aktuella klassen och alla dess underklasser skyddade int n ; //Medlem endast tillgänglig från den aktuella klassen (standard). privat int fg ; }Till skillnad från C++ måste åtkomstmodifierare anges per medlem. Anonyma klasser kan definieras i en metod som så här:
public void DoSomething () { var person = new { Namn = "Marguerite" ; Ålder = 15 ; } var pet = new { Namn = "Dunya" ; Typ = "Sköldpadda" ; Ägare = person ; } Konsol . WriteLine ( "Ålder på husdjursägare: " + husdjur . Ägare . Ålder ); }Klasser i Ruby-språket definieras enligt följande:
class MyClass def initialize # Konstruktör (valfritt) slut public # Den offentliga identifieraren är valfri eftersom inställd som standard, # indikerar att metoderna som följer den är tillgängliga var som helst i programmet def public_method # Public method end protected # Den skyddade identifieraren indikerar att följande metoder # kommer att vara tillgängliga endast för medlemmar i denna och barnklasser def protected_method # Protected method end privat # Den privata identifieraren indikerar att följande metoder # endast kommer att vara tillgängliga för medlemmar i denna klass def private_method # Privat metod slut slutSkapa en instans av en klass:
objekt = MyClass . nyAtt förstöra en instans av en klass är inte nödvändigt: det sker automatiskt med "sopsamlaren" så snart den sista referensen till den försvinner från minnet.
Definiera en klass i Python med operatorn class:
class MyClass : def __init__ ( self , arg ): """Constructor""" self . _arg = arg # objektparameter def method1 ( self , x ): """metod ingår i klassgränssnittet""" def _method2 ( self , x ): """en metod som inte ingår i ett klassgränssnitt""" def __metod2 ( själv , x ): """metoden är endast tillgänglig inom klassen""" @staticmethod def method3 ( arg1 , arg2 , ... ): """en statisk metod som kan anropas både från instanser av klassen och från själva klassen""" @classmethod def method4 ( cls , arg1 , arg2 , ... ): """klassmetod, anropbar både från instanser av klassen och från själva klassen, med tillgång till interna metoder och parametrar"""Skapa en instans av en klass:
mininstans = MyClass ( 4 )Explicit förstörelse av klassinstansen krävs inte, eftersom Python har en automatisk "sopsamlare". Du kan dock uttryckligen ta bort en referens till ett objekt (en instans av en klass eller själva klassen) så här:
del min instansDefiniera en klass i JavaScript med operatorn class:
class MyClass { constructor ( arg1 , arg2 , ...) { //constructor (valfritt) detta . arg1 = arg1 ; detta . arg2 = arg2 ; } metod1 () { // Vanlig metod } statisk metod { // Statisk metod } }Skapa en instans av en klass:
var myinstance = new MyClass ( 4 , 2 )Förstörelse av en klassinstans krävs inte: det sker automatiskt med hjälp av "sopsamlaren" så snart den sista referensen till den försvinner från minnet.
Varje klass i Java skapas vanligtvis i en separat fil, filnamnet måste matcha klassens namn. I det här fallet blir det MyClass.java
Definiera en Java -klass med operatorn class:
Skapa en instans av en klass:
MyClass my = new MyClass ( "Exempel 2" );En instans av en klass förstörs automatiskt av "sopsamlaren".
Datatyper | |
---|---|
Otolkbart | |
Numerisk | |
Text | |
Referens | |
Sammansatt | |
abstrakt | |
Övrig | |
Relaterade ämnen |