Classe (programação de computador)

Da Wikipédia, a enciclopédia livre
Ir para a navegação Saltar para pesquisar

Na programação orientada a objetos , uma classe é um modelo de código de programa extensível para criar objetos , fornecendo valores iniciais para estado ( variáveis ​​de membro ) e implementações de comportamento (funções ou métodos de membro ). [1] [2] Em muitas linguagens, o nome da classe é usado como o nome da classe (o próprio modelo), o nome do construtor padrão da classe (uma sub- rotina que cria objetos) e como o tipo de objetos gerado pela instanciação da classe; esses conceitos distintos são facilmente confundidos. [2] Embora, ao ponto de conflação, pode-se argumentar que é uma característica inerente a uma linguagem por causa de sua natureza polimórfica e por que essas linguagens são tão poderosas, dinâmicas e adaptáveis ​​para uso em comparação com linguagens sem polimorfismo presente. Assim, eles podem modelar sistemas dinâmicos (ou seja, o mundo real, aprendizado de máquina, IA) mais facilmente.

Quando um objeto é criado por um construtor da classe, o objeto resultante é chamado de instância da classe e as variáveis ​​de membro específicas do objeto são chamadas de variáveis ​​de instância , para contrastar com as variáveis ​​de classe compartilhadas na classe.

Em algumas linguagens, as classes são apenas um recurso de tempo de compilação (novas classes não podem ser declaradas em tempo de execução), enquanto em outras linguagens as classes são cidadãos de primeira classe e geralmente são objetos (tipicamente do tipo Class ou similar). Nessas linguagens, uma classe que cria classes é chamada de metaclasse .

Classe vs. tipo

No uso casual, as pessoas geralmente se referem à "classe" de um objeto, mas os objetos estritamente falando têm type : a interface, ou seja, os tipos de variáveis ​​de membro, as assinaturas de funções de membro (métodos) e as propriedades que elas satisfazem. Ao mesmo tempo, uma classe tem uma implementação (especificamente a implementação dos métodos), e pode criar objetos de um determinado tipo, com uma determinada implementação. [3] Nos termos da teoria dos tipos, uma classe é uma implementação‍—‌uma estrutura de dados concreta e uma coleção de sub-rotinas‍—‌enquanto um tipo é uma interface . Diferentes classes (concretas) podem produzir objetos do mesmo tipo (abstrato) (dependendo do sistema de tipos); por exemplo, o tipo Pilhapode ser implementado com duas classes – SmallStack (rápido para pilhas pequenas, mas escala mal) e ScalableStack (escala bem, mas com alto overhead para pilhas pequenas). Da mesma forma, uma determinada classe pode ter vários construtores diferentes.

Tipos de classe geralmente representam substantivos, como uma pessoa, lugar ou coisa, ou algo nominalizado , e uma classe representa uma implementação destes. Por exemplo, um tipo Banana pode representar as propriedades e funcionalidades de bananas em geral, enquanto as classes ABCBanana e XYZBanana representam formas de produzir bananas (digamos, fornecedores de bananas ou estruturas de dados e funções para representar e desenhar bananas em um videogame). A classe ABCBanana poderia então produzir bananas particulares: instâncias da classe ABCBanana seriam objetos do tipo Banana. Muitas vezes, apenas uma única implementação de um tipo é fornecida; nesse caso, o nome da classe geralmente é idêntico ao nome do tipo.

Design e implementação

As classes são compostas por constituintes estruturais e comportamentais. [4] As linguagens de programação que incluem classes como uma construção de programação oferecem suporte para vários recursos relacionados a classes, e a sintaxe necessária para usar esses recursos varia muito de uma linguagem de programação para outra.

Estrutura

Notação UML para classes

Uma classe contém descrições de campos de dados (ou propriedades , campos , membros de dados ou atributos ). Geralmente são tipos e nomes de campos que serão associados a variáveis ​​de estado em tempo de execução do programa; essas variáveis ​​de estado pertencem à classe ou a instâncias específicas da classe. Na maioria das linguagens, a estrutura definida pela classe determina o layout da memória usada por suas instâncias. Outras implementações são possíveis: por exemplo, objetos em Python usam contêineres de valores-chave associativos. [5]

Algumas linguagens de programação, como Eiffel, suportam a especificação de invariantes como parte da definição da classe e as impõem por meio do sistema de tipos. O encapsulamento do estado é necessário para poder impor os invariantes da classe.

Comportamento

O comportamento da classe ou de suas instâncias é definido usando métodos . Métodos são sub- rotinas com a capacidade de operar em objetos ou classes. Essas operações podem alterar o estado de um objeto ou simplesmente fornecer meios de acessá-lo. [6] Existem muitos tipos de métodos, mas o suporte para eles varia entre os idiomas. Alguns tipos de métodos são criados e chamados pelo código do programador, enquanto outros métodos especiais - como construtores, destruidores e operadores de conversão - são criados e chamados pelo código gerado pelo compilador. Uma linguagem também pode permitir que o programador defina e chame esses métodos especiais. [7] [8]

O conceito de interface de classe

Cada classe implementa (ou realiza ) uma interface fornecendo estrutura e comportamento. A estrutura consiste em dados e estado, e o comportamento consiste em código que especifica como os métodos são implementados. [9] Existe uma distinção entre a definição de uma interface e a implementação dessa interface; no entanto, essa linha é borrada em muitas linguagens de programação porque as declarações de classe definem e implementam uma interface. Algumas linguagens, no entanto, fornecem recursos que separam interface e implementação. Por exemplo, uma classe abstrata pode definir uma interface sem fornecer implementação.

As linguagens que dão suporte à herança de classes também permitem que as classes herdem interfaces das classes das quais são derivadas.

Por exemplo, se "classe A" herda de "classe B" e se "classe B" implementa a interface "interface B", então "classe A" também herda a funcionalidade (declaração de constantes e métodos) fornecida pela "interface B".

Em linguagens que suportam especificadores de acesso , a interface de uma classe é considerada o conjunto de membros públicos da classe, incluindo métodos e atributos (via métodos getter e setter implícitos ); quaisquer membros privados ou estruturas de dados internas não devem ser dependentes de código externo e, portanto, não fazem parte da interface.

A metodologia de programação orientada a objetos determina que as operações de qualquer interface de uma classe sejam independentes umas das outras. Isso resulta em um design em camadas onde os clientes de uma interface usam os métodos declarados na interface. Uma interface não exige que os clientes invoquem as operações de uma interface em qualquer ordem específica. Essa abordagem tem o benefício de que o código do cliente pode assumir que as operações de uma interface estão disponíveis para uso sempre que o cliente tiver acesso ao objeto. [10] [ citação necessária ]

Exemplo

Os botões na frente do seu aparelho de televisão são a interface entre você e a fiação elétrica do outro lado da caixa de plástico. Você pressiona o botão "power" para ligar e desligar a televisão. Neste exemplo, sua televisão específica é a instância, cada método é representado por um botão e todos os botões juntos compõem a interface (outros televisores do mesmo modelo que o seu teriam a mesma interface). Em sua forma mais comum, uma interface é uma especificação de um grupo de métodos relacionados sem qualquer implementação associada dos métodos.

Um aparelho de televisão também possui uma infinidade de atributos , como tamanho e se suporta cor, que juntos compõem sua estrutura. Uma classe representa a descrição completa de uma televisão, incluindo seus atributos (estrutura) e botões (interface).

Obter o número total de televisores fabricados pode ser um método estático da classe de televisão. Esse método está claramente associado à classe, mas está fora do domínio de cada instância individual da classe. Um método estático que encontra uma instância específica do conjunto de todos os objetos de televisão é outro exemplo.

Acessibilidade dos membros

O seguinte é um conjunto comum de especificadores de acesso : [11]

  • Private (ou class-private ) restringe o acesso à própria classe. Somente métodos que fazem parte da mesma classe podem acessar membros privados.
  • Protected (ou class-protected ) permite que a própria classe e todas as suas subclasses acessem o membro.
  • Público significa que qualquer código pode acessar o membro pelo seu nome.

Embora muitas linguagens orientadas a objetos suportem os especificadores de acesso acima, sua semântica pode ser diferente.

O design orientado a objetos usa os especificadores de acesso em conjunto com o design cuidadoso de implementações de métodos públicos para impor invariantes de classe — restrições no estado dos objetos. Um uso comum de especificadores de acesso é separar os dados internos de uma classe de sua interface: a estrutura interna se torna privada, enquanto os métodos de acesso público podem ser usados ​​para inspecionar ou alterar esses dados privados.

Os especificadores de acesso não controlam necessariamente a visibilidade , pois até mesmo membros privados podem ser visíveis para o código externo do cliente. Em algumas linguagens, um membro inacessível, mas visível, pode ser referido em tempo de execução (por exemplo, por um ponteiro retornado de uma função de membro), mas uma tentativa de usá-lo referindo-se ao nome do membro do código do cliente será impedido pelo verificador de tipos. [12]

As várias linguagens de programação orientadas a objetos impõem acessibilidade e visibilidade de membros em vários graus e, dependendo do sistema de tipos da linguagem e das políticas de compilação, aplicadas em tempo de compilação ou em tempo de execução . Por exemplo, a linguagem Java não permite a compilação de código cliente que acessa os dados privados de uma classe. [13] Na linguagem C++ , os métodos privados são visíveis, mas não acessíveis na interface; no entanto, eles podem se tornar invisíveis declarando explicitamente classes totalmente abstratas que representam as interfaces da classe. [14]

Alguns idiomas apresentam outros esquemas de acessibilidade:

  • Acessibilidade de instância versus classe : Ruby suporta especificadores de acesso privado e protegido por instância em vez de privado de classe e protegido por classe, respectivamente. Eles diferem porque restringem o acesso com base na própria instância, em vez da classe da instância. [15]
  • Friend : C++ suporta um mecanismo onde uma função explicitamente declarada como uma função amiga da classe pode acessar os membros designados como privados ou protegidos. [16]
  • Baseado em caminho : Java oferece suporte à restrição de acesso a um membro em um pacote Java , que é o caminho lógico do arquivo. No entanto, é uma prática comum ao estender uma estrutura Java implementar classes no mesmo pacote que uma classe de estrutura para acessar membros protegidos. O arquivo de origem pode existir em um local completamente diferente e pode ser implementado em um arquivo .jar diferente, mas ainda estar no mesmo caminho lógico no que diz respeito à JVM. [11]

Relações entre classes

Além do design de classes independentes, as linguagens de programação podem oferecer suporte a designs de classes mais avançados com base em relacionamentos entre classes. Os recursos de design de relacionamento entre classes normalmente fornecidos são composicionais e hierárquicos .

Composicional

As classes podem ser compostas por outras classes, estabelecendo assim uma relação de composição entre a classe envolvente e suas classes incorporadas. O relacionamento composicional entre classes também é comumente conhecido como relacionamento tem-um . [17] Por exemplo, uma classe "Carro" pode ser composta e conter uma classe "Motor". Portanto, um carro tem um motor. Um aspecto da composição é a contenção, que é o fechamento de instâncias de componentes pela instância que as possui. Se um objeto delimitador contiver instâncias de componentes por valor, os componentes e seu objeto delimitador terão um tempo de vida semelhante . Se os componentes estiverem contidos por referência, eles podem não ter uma vida útil semelhante. [18]Por exemplo, em Objective-C 2.0:

@interface  Carro  : NSObject

@property NSString * nome ;  
@property Motor * motor  
@property NSArray * pneus ;  

@fim

Essa classe Car tem uma instância de NSString (um objeto string ), Engine e NSArray (um objeto array).

Hierárquico

As classes podem ser derivadas de uma ou mais classes existentes, estabelecendo assim uma relação hierárquica entre as classes derivadas ( classes base , classes pai ousuperclasses ) e a classe derivada (classefilhaousubclasse). O relacionamento da classe derivada com as classes derivadas é comumente conhecido como um relacionamento é-um . [19] Por exemplo, uma classe 'Botão' pode ser derivada de uma classe 'Controle'. Portanto, um botãoé umcontrole. Os membros estruturais e comportamentais das classes pai sãoherdadospela classe filha. As classes derivadas podem definir membros estruturais adicionais (campos de dados) e membros comportamentais (métodos) além daqueles queherdame são, portanto,especializaçõesde suas superclasses. Além disso, as classes derivadas podemsubstituirmétodos herdados se a linguagem permitir.

Nem todos os idiomas suportam herança múltipla. Por exemplo, Java permite que uma classe implemente várias interfaces, mas apenas herde de uma classe. [20] Se herança múltipla é permitida, a hierarquia é um grafo acíclico direcionado (ou DAG para abreviar), caso contrário é uma árvore . A hierarquia tem classes como nós e relacionamentos de herança como links. Classes no mesmo nível são mais propensas a serem associadas do que classes em níveis diferentes. Os níveis dessa hierarquia são chamados de camadas ou níveis de abstração .

Exemplo (código Objective-C 2.0 simplificado, do iPhone SDK):

@interface  UIResponder  : NSObject //... @interface UIView  : UIResponder //... @interface UIScrollView  : UIView //... @interface UITableView  : UIScrollView //... 
  
  
  

Neste exemplo, um UITableView é um UIScrollView é um UIView é um UIResponder é um NSObject.

Definições de subclasse

Conceitualmente, uma superclasse é um superconjunto de suas subclasses. Por exemplo, uma hierarquia de classes comum envolveria GraphicObject como uma superclasse de Rectangle e Ellipse , enquanto Square seria uma subclasse de Rectangle . Estas também são relações de subconjuntos na teoria dos conjuntos, ou seja, todos os quadrados são retângulos, mas nem todos os retângulos são quadrados.

Um erro conceitual comum é confundir uma parte da relação com uma subclasse. Por exemplo, um carro e um caminhão são ambos os tipos de veículos e seria apropriado modelá-los como subclasses de uma classe de veículos. No entanto, seria um erro modelar as partes componentes do carro como relações de subclasse. Por exemplo, um carro é composto de motor e carroceria, mas não seria apropriado modelar motor ou carroceria como uma subclasse de carro.

Na modelagem orientada a objetos, esses tipos de relações são tipicamente modelados como propriedades de objetos. Neste exemplo, a classe Car teria uma propriedade chamada parts . partes seriam digitadas para conter uma coleção de objetos, como instâncias de Body , Engine , Tires , etc. Linguagens de modelagem de objetos como UMLincluem recursos para modelar vários aspectos de "parte de" e outros tipos de relações - dados como a cardinalidade dos objetos, restrições nos valores de entrada e saída, etc. Essas informações podem ser utilizadas por ferramentas de desenvolvedor para gerar código adicional além do básico definições de dados para os objetos, como verificação de erros nos métodos get e set . [21]

Uma questão importante ao modelar e implementar um sistema de classes de objetos é se uma classe pode ter uma ou mais superclasses. No mundo real com conjuntos reais, seria raro encontrar conjuntos que não se cruzassem com mais de um outro conjunto. No entanto, enquanto alguns sistemas como Flavors e CLOS fornecem uma capacidade para mais de um pai fazer isso em tempo de execução, apresenta uma complexidade que muitos na comunidade orientada a objetos consideram antitética aos objetivos de usar classes de objeto em primeiro lugar. Entender qual classe será responsável pelo tratamento de uma mensagem pode se tornar complexo ao lidar com mais de uma superclasse. Se usado de forma descuidada, esse recurso pode introduzir algumas das mesmas classes de complexidade e ambiguidade do sistema que foram projetadas para evitar. [22]

A maioria das linguagens modernas orientadas a objetos, como Smalltalk e Java, requerem herança única em tempo de execução. Para essas linguagens, herança múltipla pode ser útil para modelagem, mas não para implementação.

No entanto, os objetos de aplicativo da Web semântica têm várias superclasses. A volatilidade da Internet exige esse nível de flexibilidade e os padrões de tecnologia, como a Web Ontology Language (OWL) , são projetados para suportá-la.

Um problema semelhante é se a hierarquia de classes pode ou não ser modificada em tempo de execução. Linguagens como Flavors, CLOS e Smalltalk suportam esse recurso como parte de seus protocolos de metaobjeto . Como as classes são elas próprias objetos de primeira classe, é possível fazer com que elas alterem dinamicamente sua estrutura enviando-lhes as mensagens apropriadas. Outras linguagens que se concentram mais na tipagem forte, como Java e C++, não permitem que a hierarquia de classes seja modificada em tempo de execução. Os objetos da Web semântica têm a capacidade de alterar as classes em tempo de execução. O racional é semelhante à justificativa para permitir múltiplas superclasses, de que a Internet é tão dinâmica e flexível que mudanças dinâmicas na hierarquia são necessárias para gerenciar essa volatilidade. [23]

Ortogonalidade do conceito de classe e herança

Embora as linguagens baseadas em classes sejam comumente consideradas para suportar herança, a herança não é um aspecto intrínseco do conceito de classes. Algumas linguagens, muitas vezes chamadas de " linguagens baseadas em objetos ", suportam classes, mas não suportam herança. Exemplos de linguagens baseadas em objeto incluem versões anteriores do Visual Basic .

Dentro da análise orientada a objetos

Na análise orientada a objetos e na UML , uma associação entre duas classes representa uma colaboração entre as classes ou suas instâncias correspondentes. As associações têm direção; por exemplo, uma associação bidirecional entre duas classes indica que ambas as classes estão cientes de seu relacionamento. [24] As associações podem ser rotuladas de acordo com seu nome ou finalidade. [25]

Um papel de associação recebe o fim de uma associação e descreve o papel da classe correspondente. Por exemplo, uma função de "assinante" descreve a maneira como as instâncias da classe "Pessoa" participam de uma associação "assinante" com a classe "Revista". Além disso, uma "Revista" tem o papel de "revista assinada" na mesma associação. A multiplicidade de funções de associação descreve quantas instâncias correspondem a cada instância da outra classe da associação. Multiplicidades comuns são "0..1", "1..1", "1..*" e "0..*", onde o "*" especifica qualquer número de instâncias. [24]

Taxonomia de classes

Existem muitas categorias de classes, algumas das quais se sobrepõem.

Resumo e concreto

Em uma linguagem que suporta herança, uma classe abstrata , ou classe base abstrata (ABC), é uma classe que não pode ser instanciada porque é rotulada como abstrata ou simplesmente especifica métodos abstratos (ou métodos virtuais ). Uma classe abstrata pode fornecer implementações de alguns métodos e também pode especificar métodos virtuais por meio de assinaturas que devem ser implementadas por descendentes diretos ou indiretos da classe abstrata. Antes que uma classe derivada de uma classe abstrata possa ser instanciada, todos os métodos abstratos de suas classes pai devem ser implementados por alguma classe na cadeia de derivação. [26]

A maioria das linguagens de programação orientadas a objetos permite que o programador especifique quais classes são consideradas abstratas e não permitirá que elas sejam instanciadas. Por exemplo, em Java , C# e PHP , a palavra-chave abstract é usada. [27] [28] Em C++ , uma classe abstrata é uma classe que tem pelo menos um método abstrato dado pela sintaxe apropriada naquela linguagem (uma função virtual pura na linguagem C++). [26]

Uma classe que consiste apenas em métodos virtuais é chamada de Pure Abstract Base Class (ou Pure ABC ) em C++ e também é conhecida como interface pelos usuários da linguagem. [14] Outras linguagens, notadamente Java e C#, suportam uma variante de classes abstratas chamadas de interface por meio de uma palavra-chave na linguagem. Nessas linguagens, herança múltipla não é permitida, mas uma classe pode implementar múltiplas interfaces. Essa classe só pode conter métodos abstratos publicamente acessíveis. [20] [29] [30]

Uma classe concreta é uma classe que pode ser instanciada , ao contrário das classes abstratas, que não podem.

Local e interno

Em algumas linguagens, as classes podem ser declaradas em escopos diferentes do escopo global. Existem vários tipos de tais classes.

Uma classe interna é uma classe definida dentro de outra classe. A relação entre uma classe interna e sua classe que a contém também pode ser tratada como outro tipo de associação de classe. Uma classe interna normalmente não é associada a instâncias da classe delimitadora nem instanciada junto com sua classe delimitadora. Dependendo do idioma, pode ou não ser possível fazer referência à classe de fora da classe anexa. Um conceito relacionado são tipos internos , também conhecidos como tipo de dados internos ou tipo aninhado , que é uma generalização do conceito de classes internas. C++ é um exemplo de linguagem que suporta classes internas e tipos internos (via declarações typedef ). [31][32]

Outro tipo é uma classe local , que é uma classe definida dentro de um procedimento ou função. Isso limita as referências ao nome da classe dentro do escopo em que a classe é declarada. Dependendo das regras semânticas do idioma, pode haver restrições adicionais nas classes locais em comparação com as não locais. Uma restrição comum é não permitir que métodos de classe local acessem variáveis ​​locais da função delimitadora. Por exemplo, em C++, uma classe local pode se referir a variáveis ​​estáticas declaradas dentro de sua função delimitadora, mas não pode acessar as variáveis ​​automáticas da função . [33]

Metaclasses

Metaclasses são classes cujas instâncias são classes. [34] Uma metaclasse descreve uma estrutura comum de uma coleção de classes e pode implementar um padrão de projeto ou descrever tipos particulares de classes. Metaclasses são frequentemente usadas para descrever frameworks . [35]

Em algumas linguagens, como Python , Ruby ou Smalltalk , uma classe também é um objeto; portanto, cada classe é uma instância de uma metaclasse exclusiva que é incorporada à linguagem. [5] [36] [37] O Common Lisp Object System (CLOS) fornece protocolos de metaobjetos (MOPs) para implementar essas classes e metaclasses. [38]

Não subclassificável

Classes não subclassificáveis ​​permitem aos programadores projetar classes e hierarquias de classes onde em algum nível na hierarquia, derivação adicional é proibida (uma classe autônoma também pode ser designada como não subclassificável, impedindo a formação de qualquer hierarquia). Compare isso com classes abstratas , que implicam, encorajam e exigem derivação para serem usadas. Uma classe não subclassificável é implicitamente concreta .

Uma classe não subclassificável é criada declarando a classe como sealedem C# ou como finalem Java ou PHP. [39] [40] [41] Por exemplo, a classe Java Stringé designada como final . [42]

Classes não subclassificáveis ​​podem permitir que um compilador (em linguagens compiladas) execute otimizações que não estão disponíveis para classes subclassificáveis. [43]

Aula Aberta

Uma classe aberta é aquela que pode ser alterada. Normalmente, um programa executável não pode ser alterado pelos clientes. Os desenvolvedores geralmente podem alterar algumas classes, mas normalmente não podem alterar as padrão ou incorporadas. Em Ruby , todas as classes são abertas. Em Python , as classes podem ser criadas em tempo de execução e todas podem ser modificadas posteriormente. [44] As categorias Objective-C permitem que o programador adicione métodos a uma classe existente sem a necessidade de recompilar essa classe ou mesmo ter acesso ao seu código-fonte.

Mixins

Algumas linguagens têm suporte especial para mixins , embora em qualquer linguagem com herança múltipla um mixin seja simplesmente uma classe que não representa um relacionamento é um tipo de . Mixins são normalmente usados ​​para adicionar os mesmos métodos a várias classes; por exemplo, uma classe UnicodeConversionMixin pode fornecer um método chamado unicode_to_ascii quando incluído nas classes FileReader e WebPageScraper que não compartilham um pai comum.

Parcial

Nas linguagens que suportam o recurso, uma classe parcial é uma classe cuja definição pode ser dividida em várias partes, em um único arquivo de código-fonte ou em vários arquivos. [45] As partes são mescladas em tempo de compilação, fazendo com que a saída do compilador seja a mesma de uma classe não parcial.

A principal motivação para a introdução de classes parciais é facilitar a implementação de geradores de código , como designers visuais . [45] Caso contrário, é um desafio ou compromisso desenvolver geradores de código que possam gerenciar o código gerado quando ele é intercalado no código escrito pelo desenvolvedor. Usando classes parciais, um gerador de código pode processar um arquivo separado ou uma classe parcial grosseira dentro de um arquivo e, portanto, é aliviado da interjeição complexa do código gerado por meio de análise extensiva, aumentando a eficiência do compilador e eliminando o risco potencial de corromper o código do desenvolvedor. Em uma implementação simples de classes parciais, o compilador pode realizar uma fase de pré -compilaçãoonde "unifica" todas as partes de uma classe parcial. Em seguida, a compilação pode prosseguir normalmente.

Outros benefícios e efeitos do recurso de classe parcial incluem:

  • Permite a separação da interface de uma classe e do código de implementação de uma forma única.
  • Facilita a navegação por grandes classes dentro de um editor .
  • Permite a separação de interesses , de forma semelhante à programação orientada a aspectos, mas sem o uso de ferramentas extras.
  • Permite que vários desenvolvedores trabalhem em uma única classe simultaneamente sem a necessidade de mesclar código individual em um arquivo posteriormente.

Classes parciais existem em Smalltalk sob o nome de Class Extensions por um tempo considerável. Com a chegada do .NET framework 2 , a Microsoft introduziu classes parciais, suportadas em C# 2.0 e Visual Basic 2005 . WinRT também suporta classes parciais.

Exemplo em VB.NET

Este exemplo simples, escrito em Visual Basic .NET , mostra como partes da mesma classe são definidas em dois arquivos diferentes.

arquivo1.vb
 Classe  Parcial MyClass 
    Private  _name  As  String 
End  Class
arquivo2.vb
 Classe  parcial MyClass 
    Public  Readonly  Property  Name ()  As  String 
         Get 
             Return  _name 
         End  Get 
    End  Propriedade 
End  Class

Quando compilado, o resultado é o mesmo que se os dois arquivos fossem escritos como um, assim:

Classe  MyClass 
    Private  _name  As  String 
    Public  Readonly  Property  Name ()  As  String 
         Get 
             Return  _name 
         End  Get 
    End  Property 
End  Class

Exemplo em Objective-C

Em Objective-C , classes parciais, também conhecidas como categorias , podem até mesmo se espalhar por várias bibliotecas e executáveis, como no exemplo a seguir. Mas uma diferença fundamental é que as categorias do Objective-C podem sobrescrever definições em outra declaração de interface e que as categorias não são iguais à definição de classe original (a primeira requer a última). [46] Em vez disso, a classe parcial .NET não pode ter definições conflitantes, e todas as definições parciais são iguais às outras. [45]

No Foundation, arquivo de cabeçalho NSData.h:

@interface  NSData  : NSObject

-  ( id ) initWithContentsOfURL: ( NSURL * ) URL ; 
//...

@fim

Na biblioteca fornecida pelo usuário, um binário separado da estrutura Foundation, arquivo de cabeçalho NSData+base64.h:

#import <Foundation/Foundation.h>

@interface  NSData  (base64)

-  ( NSString * ) base64String ; 
-  ( id ) initWithBase64String: ( NSString * ) base64String ; 

@fim

E em um aplicativo, outro arquivo binário separado, arquivo de código-fonte main.m:

#import <Foundation/Foundation.h> 
#import "NSData+base64.h"

int main ( int argc , char * argv [])    
{
    se ( argc < 2 )   
        return EXIT_FAILURE ; 
    NSString * sourceURLString = [ NSString stringWithCString : argv [ 1 ]];    
    NSData * data = [[ NSData alloc ] initWithContentsOfURL :[ NSURL URLWithString : sourceURLString ]];      
    NSLog ( @"%@" , [ data base64String ]);  
    return EXIT_SUCCESS ; 
}

O dispatcher encontrará os dois métodos chamados na instância NSData e invocará ambos corretamente.

Não instanciado

As classes não instanciadas permitem que os programadores agrupem campos e métodos por classe que são acessíveis em tempo de execução sem uma instância da classe. De fato, a instanciação é proibida para esse tipo de classe.

Por exemplo, em C#, uma classe marcada como "static" não pode ser instanciada, só pode ter membros estáticos (campos, métodos, outros), não pode ter construtores de instância e é selada . [47]

Sem nome

Uma classe sem nome ou classe anônima é uma classe que não está vinculada a um nome ou identificador na definição. [48] ​​[49] Isso é análogo a funções nomeadas versus funções não nomeadas .

Benefícios

Os benefícios de organizar o software em classes de objetos se enquadram em três categorias: [50]

  • Desenvolvimento rápido
  • Facilidade de manutenção
  • Reutilização de código e designs

As classes de objetos facilitam o desenvolvimento rápido porque diminuem a lacuna semântica entre o código e os usuários. Os analistas de sistema podem conversar com desenvolvedores e usuários usando essencialmente o mesmo vocabulário, falando sobre contas, clientes, contas, etc. As classes de objetos geralmente facilitam o desenvolvimento rápido porque a maioria dos ambientes orientados a objetos vem com ferramentas poderosas de depuração e teste. Instâncias de classes podem ser inspecionadas em tempo de execução para verificar se o sistema está funcionando conforme o esperado. Além disso, em vez de obter despejos de memória central, a maioria dos ambientes orientados a objetos interpretou recursos de depuração para que o desenvolvedor possa analisar exatamente onde ocorreu o erro no programa e ver quais métodos foram chamados para quais argumentos e com quais argumentos. [51]

As classes de objetos facilitam a manutenção via encapsulamento. Quando os desenvolvedores precisam alterar o comportamento de um objeto, eles podem localizar a alteração apenas nesse objeto e em suas partes componentes. Isso reduz o potencial de efeitos colaterais indesejados dos aprimoramentos de manutenção.

A reutilização de software também é um grande benefício do uso de classes Object. As classes facilitam a reutilização por meio de herança e interfaces. Quando um novo comportamento é necessário, muitas vezes pode ser alcançado criando uma nova classe e fazendo com que essa classe herde os comportamentos e dados padrão de sua superclasse e, em seguida, adapte algum aspecto do comportamento ou dados de acordo. A reutilização por meio de interfaces (também conhecidas como métodos) ocorre quando outro objeto deseja invocar (em vez de criar um novo tipo de) alguma classe de objeto. Esse método de reutilização remove muitos dos erros comuns que podem entrar no software quando um programa reutiliza o código de outro. [52]

Representação em tempo de execução

Como um tipo de dados, uma classe geralmente é considerada uma construção em tempo de compilação. [53] Uma linguagem ou biblioteca também pode suportar protótipos ou metaobjetos de fábrica que representam informações em tempo de execução sobre classes, ou mesmo representar metadados que fornecem acesso a recursos de reflexão e capacidade de manipular formatos de estrutura de dados em tempo de execução. Muitas linguagens distinguem esse tipo de informação de tipo de tempo de execução sobre classes de uma classe com base no fato de que as informações não são necessárias em tempo de execução. Algumas linguagens dinâmicas não fazem distinções estritas entre construções de tempo de execução e de tempo de compilação e, portanto, podem não distinguir entre metaobjetos e classes.

Por exemplo, se Human é um metaobjeto representando a classe Person, então instâncias da classe Person podem ser criadas usando os recursos do metaobjeto Human .

Veja também

Notas

  1. ^ Gama et al. 1995 , pág. 14.
  2. ^ a b Bruce 2002 , 2.1 Objetos, classes e tipos de objetos, https://books.google.com/books?id=9NGWq3K1RwUC&pg=PA18 .
  3. ^ Gama et al. 1995 , pág. 17.
  4. ^ Gama et al. 1995 , pág. 14.
  5. ^ a b "3. Modelo de dados" . A Referência da Linguagem Python . Fundação de Software Python . Recuperado em 26/04/2012 .
  6. ^ Booch 1994 , p. 86-88.
  7. ^ "Aulas (I)" . Curso de linguagem C++ . cplusplus . com . Recuperado em 29-04-2012 .
  8. ^ "Aulas (II)" . Curso de linguagem C++ . cplusplus . com . Recuperado em 29-04-2012 .
  9. ^ Booch 1994 , p. 105.
  10. ^ Jamrich, Parsons, junho (2015-06-22). Novas perspectivas de conceitos de informática, 2016. Abrangente . Boston, MA. ISBN 9781305271616. OCLC  917155105 .
  11. ^ a b "Controlando o acesso aos membros de uma classe" . Os tutoriais de Java . Oráculo . Recuperado 2012-04-19 .
  12. ^ "OOP08-CPP. Não retorne referências a dados privados" . CERT C++ Secure Coding Standard . Universidade Carnegie Mellon. 2010-05-10. Arquivado a partir do original em 2015-10-03 . Recuperado em 2012-05-07 .
  13. ^ Ben-Ari, Mordechai (2007-01-24). "2.2 Identificadores" (PDF) . Erros de compilação e tempo de execução em Java . Recuperado em 2012-05-07 .
  14. ^ a b Selvagem, Fred. "Interfaces C++" . Dr. Dobb . UBM Techweb . Recuperado em 2012-05-02 .
  15. ^ Tomás; Caçar. "Classes, Objetos e Variáveis" . Programação Ruby: O Guia do Programador Pragmático . Ruby-Doc.org . Recuperado em 26/04/2012 .
  16. ^ "Amizade e herança" . Curso de linguagem C++ . cplusplus . com . Recuperado em 26/04/2012 .
  17. ^ Booch 1994 , p. 180.
  18. ^ Booch 1994 , p. 128-129.
  19. ^ Booch 1994 , p. 112.
  20. ^ a b "Interfaces" . Os tutoriais de Java . Oráculo . Recuperado em 2012-05-01 .
  21. Berfeld, Marya (2 de dezembro de 2008). "Transformação de UML para Java nas edições do IBM Rational Software Architect e software relacionado" . IBM . Recuperado em 20 de dezembro de 2013 .
  22. ^ Jacobsen, Ivar; Magnus Christerson; Patrik Jonsson; Gunnar Overgaard (1992). Engenharia de Software Orientada a Objetos . Addison-Wesley ACM Press. págs.  43–69 . ISBN 0-201-54435-0.
  23. ^ Knublauch, Holger; Oberle, Daniel; Tetlow, Phil; Wallace, Evan (2006-03-09). "Um Primer da Web Semântica para Desenvolvedores de Software Orientados a Objetos" . W3C . Recuperado em 30-07-2008 .
  24. ^ a b Bell, Donald. "Noções básicas de UML: O diagrama de classes" . trabalho do desenvolvedor . IBM . Recuperado em 2012-05-02 .
  25. ^ Booch 1994 , p. 179.
  26. ^ a b "Polimorfismo" . Curso de linguagem C++ . cplusplus . com . Recuperado em 2012-05-02 .
  27. ^ "Métodos e classes abstratos" . Os tutoriais de Java . Oráculo . Recuperado em 2012-05-02 .
  28. ^ "Abstração de classe" . Manual do PHP . O Grupo PHP . Recuperado em 2012-05-02 .
  29. ^ "Interfaces (Guia de Programação C#)" . Guia de programação C# . Microsoft . Recuperado 2013-08-15 .
  30. ^ "Herança (Guia de Programação C#)" . Guia de programação C# . Microsoft . Recuperado em 2012-05-02 .
  31. ^ "Classes aninhadas (somente C++)" . XL C/C++ V8.0 para AIX . IBM . Recuperado em 2012-05-07 .
  32. ^ "Nomes de tipos locais (somente C++)" . XL C/C++ V8.0 para AIX . IBM . Recuperado em 2012-05-07 .
  33. ^ "Classes locais (somente C++)" . XL C/C++ V8.0 para AIX . IBM . Recuperado em 2012-05-07 .
  34. ^ Booch 1994 , p. 133-134.
  35. ^ "13 Classes e metaclasses" . pharo.gforge.inria.fr . Recuperado em 31/10/2016 .
  36. ^ Tomás; Caçar. "Classes e Objetos" . Programação Ruby: O Guia do Programador Pragmático . Ruby-Doc.org . Recuperado em 2012-05-08 .
  37. ^ Booch 1994 , p. 134.
  38. ^ "MOP: Conceitos" . O Protocolo MetaObject do Common Lisp Object System . Associação de Usuários Lisp. Arquivado do original em 2010-11-15 . Recuperado em 2012-05-08 .
  39. ^ "selado (Referência C#)" . Referência C# . Microsoft . Recuperado em 2012-05-08 .
  40. ^ "Escrevendo Classes e Métodos Finais" . Os tutoriais de Java . Oráculo . Recuperado em 2012-05-08 .
  41. ^ "PHP: Palavra-chave final" . Manual do PHP . O Grupo PHP . Recuperado em 21/08/2014 .
  42. ^ "String (Plataforma Java SE 7)" . Plataforma Java, Standard Edition 7: Especificação de API . Oráculo . Recuperado em 2012-05-08 .
  43. ^ Marca, Sy. "Os benefícios de desempenho das aulas finais" . Blog da equipe Microsoft C++ . Microsoft . Recuperado em 4 de abril de 2020 .
  44. ^ "9. Aulas" . O Tutorial Python . Python.org . Recuperado em 3 de março de 2018 . Como acontece com os módulos, as classes participam da natureza dinâmica do Python: elas são criadas em tempo de execução e podem ser modificadas ainda mais após a criação.
  45. ^ a b c mairaw; Bill Wagner; tompratt-AQ (2015-09-19), "Partial Classes and Methods" , C# Programming Guide , Microsoft , recuperado 2018-08-08
  46. ^ Apple (2014-09-17), "Personalizando classes existentes" , Programando com Objective-C , Apple , recuperado 2018-08-08
  47. ^ "Classes estáticas e membros de classe estática (guia de programação C#)" . Guia de programação C# . Microsoft . Recuperado em 2012-05-08 .
  48. ^ "Classes Anônimas (Os Tutoriais Java™ > Aprendendo a Linguagem Java > Classes e Objetos)" . docs.oracle.com . Recuperado 2021-05-13 .
  49. ^ "PHP: aulas anônimas - Manual" . www.php.net . Recuperado 2021-08-11 .
  50. ^ "O que é um objeto?" . oracle . com . Corporação Oracle . Recuperado em 13 de dezembro de 2013 .
  51. ^ Booch, Grady; Robert A. Maksimchuk; Michael W. Engle; Bobbi J. Young Ph.D.; Jim Conallen; Kelli A. Houston (30 de abril de 2007). Análise e Design Orientado a Objetos com Aplicativos . Profissional Addison-Wesley. págs. 1–28. ISBN 978-0-201-89551-3. Recuperado em 20 de dezembro de 2013 . Existem fatores limitantes fundamentais da cognição humana; podemos abordar essas restrições por meio do uso de decomposição, abstração e hierarquia.
  52. ^ Jacobsen, Ivar; Magnus Christerson; Patrik Jonsson; Gunnar Overgaard (1992). Engenharia de Software Orientada a Objetos . Addison-Wesley ACM Press. ISBN 0-201-54435-0.
  53. ^ "Padrão internacional C++" (PDF) . Rascunho de Trabalho, Padrão para Linguagem de Programação C++ . ISO/IEC JTC1/SC22 WG21 . Recuperado em 5 de janeiro de 2020 .

Referências

Leitura adicional

0.071502923965454