Pessoalmente, as chamadas classes em programação são o mesmo conceito que as classes no mundo real que classificam objetos, mas são emprestados na programação. As classes representam coisas que têm uma série de pontos em comum e as mesmas operações ou ações, que são tipos de dados abstratos em programação. Cada indivíduo específico (no mundo real) e variáveis de instância (para programação) são objetos.
Uma classe é uma representação de recursos comuns (atributos e operações) de certos objetos no mundo real, e um objeto é uma instância de uma classe.
Atributos de classe: é a abreviação dos atributos estáticos de uma classe, que se refere a vários dados contidos na classe, como variáveis ou outros objetos de classe;
Um serviço de classe: é chamado de função ou método de membro.
¨
A forma de definição de uma classe em Java é a seguinte:
Classe [Modificador] Nome da classe [estende a classe pai] [Nome da interface implementa {classe Declaração de Declaração da Variável de Classe Declaração do Método}Vamos falar sobre cada parte disso em detalhes:
Antes da palavra -chave da classe, os modificadores de classe são geralmente divididos em três tipos: Modificadores de acesso a classe pública pública, modificador final (especificador de classe final) e modificador abstrato (especificador de classe abstrato)
Entre eles, o modificador de permissão só pode ser público ou padrão (ou seja, vazio, nada, indicando que é definido como amigável), e o público significa que a classe pode ser usada e acessada em qualquer lugar (desde que o programa possa encontrar a localização da classe), seja no mesmo pacote ou em pacotes diferentes. Observe que isso é diferente de C ++. O C ++ não possui um modificador para restringir os direitos de acesso à classe, mas possui direitos de acesso às relações de herança entre as classes. Além disso, todos eles têm direitos de acesso aos atributos e métodos de classe. A permissão de acesso padrão (ou seja, definida como amigável) significa que ele só pode ser referenciado e acessado por classes no mesmo pacote, mas não pode ser acessado e referenciado por classes em outros pacotes, mesmo se importados.
Também será mencionado mais tarde: quando o modificador padrão de um atributo e método de classe for usado, também é expressa que ele só pode ser referenciado e acessado por classes no mesmo pacote.
A herança múltipla não é permitida em Java, que é diferente de C ++. Para compensar essa falha, a Java introduziu o conceito de interface.
Na definição da classe acima, o corpo da classe contém principalmente o conteúdo específico da classe, incluindo os atributos da classe e os métodos da classe. As propriedades de uma classe podem ser variáveis simples ou instâncias de determinadas classes. Se for uma instância de uma classe, ela pode ser definida da seguinte forma:
[Modificador] nome da classe Nome do objeto = novo nome da classe (lista de parâmetros);
Ao declarar objetos e variáveis complexas, você não pode usar a criação durante as declarações, mas pode ser criado em futuros construtores.
Os métodos definidos em uma classe geralmente desempenham duas funções: uma é executar várias operações em torno dos atributos da classe; O outro é executar a troca de dados, entrega de mensagens e outras operações com outras classes ou objetos.
A sintaxe para declarar métodos em Java é a seguinte:
[Modificador] Nome do método do tipo de valor de retorno (lista de parâmetros) lança o nome da exceção 1, nome da exceção 2,… {Método Body: Declaração da variável local; sequência de declaração;}Os métodos de classe, também conhecidos como funções membros, são usados para especificar operações nos atributos de classe e implementar funções internas das classes. Eles também são uma janela importante para as aulas interagirem com o mundo exterior.
Os programadores Java se concentram na criação de tipos definidos pelo usuário chamados classes. As classes também são chamadas de tipos definidos por programador. Cada classe contém dados e um conjunto de métodos para manipular dados. A parte dos dados da classe é chamada de variáveis de instância. Uma instância de um tipo definido pelo usuário (ou seja, uma classe) é chamado de objeto.
Um objeto é uma instância de uma classe. Uma classe é uma abstração do mesmo tipo de objeto e um modelo para criar um objeto. Criar um objeto no programa abrirá um espaço na memória, incluindo as propriedades e métodos do objeto. Crie um objeto usando o operador de palavras -chave novo.
Construtor (pode ser comparado com C ++, que é quase o mesmo que C ++)
Crie seu próprio construtor
• O nome do construtor e o nome da classe são os mesmos. Ao construir um objeto da classe de funcionários, esse construtor é iniciado e o campo da instância recebe um valor inicial. Em Java, a definição e a inicialização são unificadas - ambas são indispensáveis.
Por exemplo, ao criar uma instância da classe de funcionários com o seguinte código,
NewEmployee ("James Bond", 100000,1950,1,1);
As características do construtor são:
(1) O construtor e a classe têm o mesmo nome.
(2) Uma classe pode ter vários construtores.
(3) O construtor pode ter 0, 1 ou mais parâmetros.
(4) O construtor não tem valor de retorno.
(5) O construtor é sempre chamado com o novo operador.
O papel do construtor
(1) Inicialização do objeto
(2) Introduzir mais flexibilidade (atribuição variável ou operações mais complexas)
(3) O construtor não pode ser definido em java
Um construtor não pode ser definido em Java, e o sistema gerará automaticamente um construtor padrão para o sistema. O nome deste construtor é o mesmo que o nome da classe, ele não possui parâmetros formais e não executa nenhuma operação.
Visão geral do método
Um programa Java é composto de definições de classe e a classe possui duas partes: propriedades e métodos. O que é uma classe de descrição do atributo e o que é uma classe de descrição do método. Qualquer objeto tem memória independente para armazenar suas propriedades. Todos os objetos da classe compartilham o método armazenado na memória.
Em outras palavras: os métodos são o principal componente da classe. Em uma classe, o papel de um programa se reflete no método.
O método é criar uma sub -rotina nomeada por Java. Um método principal e vários sub-metodos. O método principal chama outros métodos e outros métodos também podem ser chamados um para o outro, e o mesmo método pode ser chamado a qualquer momento por um ou mais métodos.
Definir outro método em um método produzirá um erro de sintaxe.
(1) É melhor evitar variáveis locais de "máscara" variáveis. Isso pode ser feito sem usar o identificador de mesmo nome em uma classe; Os parâmetros nas chamadas de método são usados para passar valores e referências numéricas, e os métodos também podem ser chamados em aninhados e recursivamente.
(2) Se um tipo de valor de retorno não void for especificado no corpo do método, o método deverá incluir uma declaração de retorno para garantir que haja um valor de retorno em qualquer caso e a declaração de retorno não possa ser seguida por nenhuma expressão;
A estrutura básica dos programas Java é a seguinte:
Introduzir biblioteca de classe Java; Defina a classe 1 do usuário 1 {defina várias variáveis ou objetos da classe 1: defina o método 1 da classe 1; definir o método 2 da classe 1; … Defina o método M1 da classe 1; } Defina o usuário classe 2 {defina várias variáveis ou objetos da classe 2: define o método 1 da classe 2; definir o método 2 da classe 2; … Defina o método m2 da classe 2}A Java introduziu o conceito de "Modificador de Controle de Acesso" que permite que os criadores da biblioteca declarem o que pode ser usado pelos programadores de clientes e o que não pode ser usado.
Esse nível de controle de acesso está entre o intervalo de "acesso máximo" e "acesso mínimo", incluindo: público, "padrão" (nenhuma palavra -chave), protegida e privada. A lista a seguir explica o significado dos modificadores de controle de acesso:
Caráter de controle de acesso público
Para aulas:
Existe apenas um controlador de acesso para uma aula em Java: Public, isto é, público. Uma classe é declarada como classe pública, indicando que pode ser acessada e referenciada por todas as outras classes. Acesso e referência aqui refere -se à classe ser visível e utilizável como um todo. Outras partes do programa podem criar objetos desta classe, acessar variáveis de membros visíveis dentro da classe e chamar seus métodos visíveis.
Uma classe é visível para outras partes do programa como um todo e não representa que todas as propriedades e métodos da classe também são visíveis para outras partes do programa. O primeiro é apenas uma condição necessária para o último. Se as propriedades e métodos da classe podem ser acessados por todas as outras classes, depende dos caracteres de controle de acesso dessas propriedades e métodos.
Usado para propriedades em classe:
Os atributos em classe modificados com o público são chamados de atributos públicos. Se esta classe for uma classe pública, ela pode ser acessada por todas as outras classes.
Controle de acesso padrão
Usado para aulas
Se uma classe não possui caracteres de controle de acesso, significa que possui as características de controle de acesso padrão. Esse controle de acesso padrão estipula que a classe só pode ser acessada e referenciada pelas classes no mesmo pacote e não pode ser usada por classes em outros pacotes. Esse recurso de acesso é chamado de acessibilidade do pacote. Ao declarar os caracteres de controle de acesso da classe, toda a estrutura do programa pode ser clara e rigorosa, reduzindo a possível interferência e erros entre classes.
Usado para atributos de classe
Se as propriedades e métodos da classe não forem limitados pelos símbolos de controle de acesso, eles também indicam que são acessibilidade de pacotes.
3 Personagem de controle de acesso privado privado
Atributos ou métodos modificados com privado só podem ser acessados e modificados pela própria classe, e não podem ser obtidos e referenciados por qualquer outra classe, incluindo subclasses da classe.
1). Os dados privados, por exemplo, possuem três campos de instância, que contêm dados que são operados dentro de uma instância da classe de funcionários.
nome de string privado;
Salário duplo privado;
data privada HIREDAY;
A palavra -chave privada é usada para garantir que esses campos de instância só possam ser acessados pela própria classe dos funcionários.
2). Método privado Ao implementar a classe, tornamos todos os campos de dados privados porque os dados públicos são perigosos. Qual é a situação com o método? Embora a maioria dos métodos seja pública, os métodos privados também são usados com frequência. Esses métodos só podem ser separados pelo mesmo método.
Em resumo, o método privado pode ser selecionado nos seguintes casos:
(1) Os métodos que não estão relacionados ao usuário da classe.
(2) Os métodos que não são fáceis de manter se a implementação da classe for alterada.
Caractere de controle de acesso protegido protegido
As variáveis de membro modificadas com protegidas podem ser referenciadas por três tipos: a própria classe, outras classes no mesmo pacote que ele e subclasses da classe em outros pacotes. O principal objetivo do uso do modificador protegido é permitir que suas subclasses em outros pacotes acessem propriedades específicas da classe pai.
A palavra -chave protegida nos apresenta um conceito chamado "herança", que se baseia nas classes existentes e adiciona novos membros a ele sem afetar as classes existentes - chamamos essa classe existente de "classe base" ou "classe base". Também pode alterar o comportamento dos membros existentes dessa classe. Para herança de uma classe existente, dizemos que nossa nova classe "estende" a classe existente
Personagem de controle de acesso protegido privado protegido privado
Privado e protegido são usados na sequência para formar um caractere completo de controle de acesso: caractere de controle de acesso à proteção privada. As variáveis de membro modificadas com o PrivateProtected podem ser acessadas e referenciadas por duas classes, uma é a própria classe e a outra é todas subclasses da classe, se essas subclasses estão no mesmo pacote da classe ou em outros pacotes.
Comparado ao protegido, o Modificador Protegido Private exclui não subclasses dentro do mesmo pacote do escopo acessível, tornando as variáveis de membros mais proprietárias a classes com relações explícitas de herança, em vez de pacotes que são vagamente agrupados.
Modificador estático
A estática é chamada de modificador estático, que modifica propriedades e métodos em uma classe.
O uso da palavra -chave estática pode atender a dois requisitos:
(1) Uma situação é que você deseja usar apenas uma área de armazenamento para salvar dados específicos - não importa quantos objetos você queira criar, você nem cria objetos; Os atributos modificados pela estática são chamados de propriedades estáticas, e um dos recursos mais essenciais desse tipo de atributo é que eles são atributos de uma classe, não objetos específicos de qualquer classe. Em outras palavras, para qualquer objeto específico desta classe, uma propriedade estática é uma unidade de armazenamento comum. Quando qualquer objeto de qualquer classe o acessar, ele recebe o mesmo valor numérico. Quando qualquer objeto de qualquer classe o modifica, ele também está fazendo operações na mesma unidade de memória.
(2) Outra situação é que precisamos de um método especial que não esteja associado a nenhum objeto desta classe. Ou seja, mesmo que o objeto não seja criado, é necessário um método que possa ser chamado diretamente pela classe.
Um objetivo importante da estática é nos ajudar a chamar esse método sem ter que criar um objeto.
Constantes estáticas
Variáveis estáticas são raras. No entanto, constantes estáticas são comuns. Por exemplo, uma constante estática é definida na aula de matemática:
Matemática de classe pública
{… Public estático final duplo pi = 3.1.4159265358979323846;…} Um método estático declara que um método é estático tem pelo menos três significados:
(1) Ao usar esse método, o nome da classe deve ser usado como prefixo, em vez de um nome de objeto específico;
(2) Métodos não estáticos são métodos pertencentes a um objeto. Quando esse objeto é criado, o método do objeto tem seu próprio segmento de código dedicado na memória; enquanto o método estático pertence a toda a classe, e seu segmento de código na memória será alocado e carregado de acordo com a definição da classe e não será exclusivo de nenhum objeto;
(3) Como o método estático pertence a toda a classe, ele não pode manipular e processar variáveis de membros pertencentes a um determinado objeto, mas só pode processar variáveis de membros pertencentes a toda a classe.
5 Método principal
O método principal não aplica operações a nenhum objeto. De fato, quando o programa começa a executar, ainda não existem objetos. O método estático é executado e os objetos exigidos pelo programa são construídos.
Ele solicita que cada classe possa ter um método principal. Este é um truque muito conveniente para as aulas de teste de unidade.
Resumo é um modificador abstrato que pode ser usado para modificar classes ou métodos.
Classe abstrata
Quando uma classe é declarada como abstrata, essa classe é chamada de classe abstrata. A chamada classe abstrata é uma classe sem objetos de instância concreta.
Para resolver esse problema, o Java fornece um mecanismo chamado "Método abstrato". Pertence a um método incompleto, com apenas uma declaração, e não possui órgão de método. Aqui está a sintaxe usada ao declarar métodos abstratos:
Resumo Void X ();
Métodos abstratos
Como modificador de método de classe, o abstrato declara um método abstrato que possui apenas cabeçalhos de método, mas nenhum corpo específico de método e implementação de operação.
Pode -se observar que o método abstrato tem apenas a declaração do cabeçalho do método e um ponto de vírgula é usado para substituir a definição do corpo do método: quanto à implementação específica do corpo do método, é concluído por diferentes subclasses da classe atual em suas respectivas definições de classe.
Deve -se notar que todos os métodos abstratos devem existir em classes abstratas
meio.
Além dos métodos abstratos, as classes abstratas também podem ter dados e métodos concretos.
Métodos abstratos são conceitos muito importantes na linguagem de programação Java. Você o usará de várias maneiras na interface.
Nota: Aqui precisamos comparar e memorizar com a interface. Os métodos na interface são métodos abstratos. Obviamente, também existem atributos na interface, e suas propriedades específicas serão descritas em detalhes posteriormente.
Classe final, atributo final, método final e finalizador (não há modificador final no C ++)
Final é o modificador final, que modifica classes, propriedades e métodos. Além disso, as palavras -chave do terminal são muito semelhantes à final e serão introduzidas juntas
Classe final
Se uma classe for declarada final, significa que ela não pode derivar novas subclasses e não pode ser herdada como uma classe pai. Portanto, uma classe não pode ser declarada abstrata e final.
As classes definidas como final são geralmente algumas classes com funções especiais usadas para concluir as funções padrão. Definir uma classe como final pode corrigir seu conteúdo, atributos e funções e formar uma relação de mapeamento estável com seu nome de classe, garantindo assim que as funções implementadas quando se referirem a esta classe sejam precisas.
Atributos finais
Muitas linguagens de programação têm suas próprias maneiras de dizer ao compilador que um determinado dado é uma "constante". As constantes são usadas principalmente nos dois aspectos a seguir:
(1) Período de compilação constante, nunca mudará;
(2) Não queremos um valor inicializado durante o tempo de execução para alterar.
Um campo de instância pode ser definido como final (não pode ser alterado). Este campo deve ser inicializado quando o objeto é construído. Ou seja, deve -se garantir que o valor tenha sido definido antes do final de cada construtor. O valor do campo não pode ser alterado no futuro
Método final
O motivo do uso do método final pode ser devido a considerações por dois motivos.
O primeiro é "bloquear" o método para impedir que qualquer classe de herança mude seu significado original. Ao projetar um programa, essa prática pode ser realizada se você quiser que o comportamento de um método permaneça inalterado durante a herança e não puder ser substituído ou reescrito.
A segunda razão para adotar o método final é a eficiência da execução do programa
Terminator
A função do terminador é um método executado ao recuperar objetos. Semelhante ao método que os construtores são executados ao criar objetos.
exemplo
Protected voidfinalize () {System.out.println (""); }Outros modificadores
volátil
Se um atributo for modificado por um volátil, significa que esse atributo pode ser controlado e modificado por vários threads ao mesmo tempo.
sincronizado
Usado principalmente para sincronização de threads
nativo
Isso significa que o método não está escrito na linguagem Java (está escrito em C, C ++ e outros idiomas)
Algumas informações encontradas online: - categoria interna
Simplificando, as classes internas são classes nas classes, por exemplo:
classe a {private int i; private void m () {} classe b {mm (int j) {i = j; m ();}}}Aqui, B é a classe interna de A, que é caracterizada por acesso conveniente a métodos e propriedades privadas em classes externas. Por exemplo, aqui B pode acessar diretamente as propriedades privadas i e os métodos privados m () em A.
As características mais importantes da programação orientada a objetos são o encapsulamento (também chamado de abstração), herança e polimorfismo. Como uma linguagem de programação orientada a objetos, Java tem suas próprias vantagens a esse respeito:
"A herança é uma forma de reutilização de software, que é eficaz na redução da complexidade do software. A herança também é uma característica de uma linguagem de programação orientada a objetos. Linguagens que adotam objetos, mas não têm herança são idiomas baseados em objetos, mas não linguagens orientadas a objetos. Essa é a diferença entre os dois".
A relação de herança entre as classes é uma simulação direta das relações genéticas no mundo real. Representa a conexão intrínseca entre as classes e o compartilhamento de atributos e operações, ou seja, as subclasses podem seguir certos recursos da classe pai (classe herdada). Obviamente, as subclasses também podem ter suas próprias propriedades e operações independentes
A herança é uma forma de reutilização de software. Novas classes são geradas por classes existentes, e novos atributos e comportamentos são adicionados mantendo suas propriedades e comportamentos e modificando o desempenho de acordo com os requisitos da nova classe. Se uma classe infantil herda apenas de uma classe pai, é chamada de herança única; Se uma classe infantil herda de mais de uma classe pai, é chamada de multi-aprimoramento. Observe que o Java não suporta herança múltipla, mas suporta o conceito de "interface". As interfaces permitem que o Java obtenha muitas vantagens de herança múltipla e abandone as desvantagens correspondentes. Nota: C ++ suporta herança múltipla
Definição de relação de herança:
[Modificador] Nome da subclasse da classe estende o nome da classe pai, nome da classe pai 2
O nome da classe pai segue se estende
A palavra -chave é usada para indicar qual subclasse da classe atual já está lá e há um relacionamento de herança.
Defina duas subclasses do funcionário dos funcionários:
Categoria geral de funcionários: CommonEmployee
Categoria Supervisor: GerenciadorEmployee
Existem dois aspectos principais da herança da subclasse da classe dos pais:
(1) herança de atributos. Por exemplo, uma empresa é uma classe pai e uma empresa tem um nome, endereço, gerente, funcionário etc., que são todos os aspectos estruturais.
(2) herança do método. Uma classe pai define várias operações, como uma empresa que precisa ter projetos, lucros, nomeação de gerentes, recrutar funcionários etc., e a subsidiária também herdará essas ações s;
ClassCommonEmployeeextends Employee // Subclasse 1: {intm_managerno; // Definir o atributo de classe M_Managerno, representando o número do chefe do funcionário} ClassManagerEmployeeextends Employee // Subclasse 2: {intm_secretaryno; //Fine attribute m_secretaryNo, representante do secretário: Herança de atributo e esconderijo
Embora a classe dos funcionários seja uma classe pai, isso não significa que ela tenha mais funções apenas porque é uma classe pai. Pelo contrário, os subanalogs têm mais funções do que suas classes pais. Como a subclasse é uma extensão da classe pai, os atributos e métodos que a classe pai não possui são adicionados (1) A subclasse não pode acessar o membro privado da classe pai, mas a subclasse pode acessar o público de sua classe pai.
(2) O acesso protegido é um nível intermediário protetor entre acesso público e privado.
(3) Como os membros da classe dos pais herdados não estão listados na declaração da subclasse, esses membros existem na subclasse.
Aqui, precisamos distinguir entre herança, substituição e sobrecarga, vários conceitos confusos:
Somente no nível conceitual do método, esses três conceitos podem ser facilmente confundidos:
Herança do método
Para objetos de subclasse, os métodos da classe pai podem ser usados. Mesmo que esses métodos não estejam claramente definidos na subclasse, eles são automaticamente herdados da classe pai.
Cobertura do método
A substituição do método refere -se a: um método que define um método com o mesmo nome para substituir a classe pai, que é uma implementação da tecnologia polimórfica. Quando o método da classe pai é substituído na classe infantil, geralmente é a versão da classe infantil que chama a versão da classe pai e faz algum trabalho adicional.
Há muitas coisas a serem observadas. Aqui, eu mencionei principalmente isso e super. Existe isso em C ++ (e o conceito é semelhante ao de Java), mas não há super.
Isso representa o próprio objeto atual e representa uma referência ao objeto atual. Pode ser entendido como outro nome do objeto. Isso permite chamar os métodos e propriedades do objeto atual.
Por exemplo: this.getName () e getName () são os mesmos na classe.
Super representa o objeto de classe pai direta do objeto atual e é a sobrecarga do método de referência do objeto da classe pai do objeto atual.
Definição de sobrecarga: o método pode ser definido com o mesmo nome do método, mas diferentes tabelas de parâmetros (o número, tipo ou ordem dos parâmetros na tabela de parâmetros possuem valores diferentes), que é chamado de sobrecarga do método.
• Sobrecarga: a sobrecarga ocorre quando vários métodos têm o mesmo nome e contêm parâmetros diferentes. O compilador deve escolher qual método chamar. Ele escolhe o método correto comparando os tipos de parâmetros em diferentes cabeçalhos de método com os tipos de valores usados em chamadas de método específicas.
O polimorfismo permite o processamento de variáveis existentes e classes relacionadas em um estilo unificado, facilitando a adição de novos recursos no sistema. Aqui, publicar as informações que você encontrou on -line pode esclarecer mais claramente os polimorfismos e os problemas de herança que precisam de atenção especial na herança:
Polimorfismos de Java
A programação orientada a objetos tem três características, a saber, o encapsulamento, a herança e o polimorfismo.
O encapsulamento oculta o mecanismo de implementação interna da classe, para que a estrutura interna da classe possa ser alterada sem afetar o usuário, protegendo os dados.
A herança é reutilizar o código da classe pai enquanto se prepara para a implementação do polimorfismo. Então, o que é o polimorfismo?
A reescrita, a sobrecarga e a conexão dinâmica do método constituem polimorfismo. Uma das razões pelas quais Java introduziu o conceito de polimorfismo é que ele é diferente do C ++ em termos de herança de classe. O último permite a herança múltipla, o que traz funções muito poderosas, mas a complexa relação de herança também traz maiores problemas aos desenvolvedores de C ++. Para evitar riscos, o Java permite apenas a herança única, e existe uma relação IS entre classes derivadas e classes base (ou seja, "gatos" é um "animal"). Embora fazer isso garante a simplicidade e a clareza da relação de herança, ele terá inevitavelmente grandes limitações funcionais. Portanto, Java introduziu o conceito de polimorfismo para compensar essa falha. Além disso, classes e interfaces abstratas também são meios importantes para resolver as limitações dos regulamentos de herança única. Ao mesmo tempo, o polimorfismo também é a essência da programação orientada a objetos.
Para entender o polimorfismo, você deve primeiro saber o que é "transformação ascendente".
Eu defini um gato de subclasse, que herda a classe de animais, e o último é que o primeiro é a classe dos pais. Eu posso passar
Gato c = novo gato ();
Instantar um objeto de gato não é difícil de entender. Mas quando eu defino assim:
Animal a = novo gato ();
O que isto significa?
É simples, significa que eu defino uma referência do tipo animal a um objeto recém -criado do tipo CAT. Como o CAT é herdado de seu animal de classe pai, uma referência a um tipo de animal pode apontar para um objeto de um tipo de gato. Então, qual é o sentido de fazer isso? Como as subclasses são uma melhoria e extensão para a classe pai, as subclasses são geralmente mais poderosas que as classes -pais em função, e seus atributos são mais exclusivos que as classes dos pais.
Definir uma referência a um tipo de classe pai aponta para um objeto subclassificado pode não apenas usar as funções poderosas da subclasse, mas também extrair os pontos em comum da classe pai.
Portanto, uma referência ao tipo de classe pai pode chamar todas as propriedades e métodos definidos na classe pai e é impotente para métodos definidos na classe infantil, mas não na classe pai;
Ao mesmo tempo, um método na classe pai só pode ser chamado por uma referência ao tipo de classe pai se for definido na classe pai, mas não substituído na classe infantil;
Para métodos definidos na classe pai, se o método for reescrito na classe infantil, a referência ao tipo de classe pai chamará esse método na classe infantil, que é uma conexão dinâmica.
Veja o seguinte programa:
classe pai {public void func1 () {func2 (); } // Este é o método FUNC2 () na classe pai, porque o método é substituído na subclasse abaixo // quando chamado na referência do tipo de classe pai, esse método não será mais válido // substituir o método FUNC2 () substituído na subclasse vazio público func2 () {System.out.println ("AAA"); }} classe Child estende o pai {// func1 (int i) é uma sobrecarga do método func1 () // Como esse método não é definido na classe dos pais, ele não pode ser chamado pela referência do tipo de classe pai // SO no método principal abaixo da criança. } // func2 () reescreva o método func2 () no pai da classe pai // se o método func2 () for chamado na referência ao tipo de classe pai, ele deve ser o método reescrito na subclasse public void func2 () {System.out.println ("ccc"); }} classe pública polymorphismTest {public static void main (string [] args) {filho filho = novo filho (); Child.func1 (); // Qual será o resultado da impressão? }}O programa acima é um exemplo muito típico de polimorfismo. A criança da classe infantil herda o pai da classe dos pais, sobrecarrega o método da classe pai func1 () e substitui o método da classe dos pais FUNC2 (). O func1 sobrecarregado (int i) e o func1 () não são mais o mesmo método. Como não há func1 (int i) na classe pai, o filho de referência do tipo de classe pai não pode chamar o método func1 (int i). Se a subclasse substituir o método FUNC2 (), o filho de referência do tipo de classe pai chamará o Func2 () reescrito na subclasse ao chamar o método.
Então, quais resultados o programa imprimirá?
Obviamente, deve ser "CCC".
Para o polimorfismo, pode ser resumido como:
(1) use referências do tipo de classe pai para apontar para o objeto da subclasse (objeto real);
(2) essa referência pode chamar apenas métodos e variáveis definidas na classe pai;
(3) Se um método na classe pai for reescrito na subclasse, ao chamar esse método, o método na subclasse será chamado; (conexão dinâmica, chamada dinâmica)
(4) As variáveis não podem ser reescritas (substituídas). O conceito de "reescrita" é apenas para métodos. Se as variáveis na classe pai forem "reescrever" na subclasse, um erro será relatado durante a compilação.
O polimorfismo é através de:
(1) A interface e implemente a interface e substitui várias classes diferentes que cobrem o mesmo método na interface (2) a classe pai e a classe pai e a classe pai e substituem várias subclasses diferentes que cobrem o mesmo método na classe pai.
1. Conceitos básicos
Polimorfismo: envie uma mensagem para um objeto e deixe o objeto decidir a qual comportamento responder.
As chamadas de método dinâmico são implementadas atribuindo referências de objeto de subclasse a variáveis de referência de objeto de superclasse.
Esse mecanismo de Ava segue um princípio: quando um objeto de superclasse se refere a uma variável para se referir a um objeto de subclasse, o tipo do objeto referenciado, em vez do tipo de variável referenciada, determina cujo método de membro é chamado, mas o método chamado deve ser definido na superclasse, ou seja, o método coberto pela subclasse.
(1) Se A é uma referência à Classe A, pode apontar para uma instância da Classe A, ou a uma subclasse da classe A.
(2) Se A é uma referência à interface A, é necessário apontar para uma instância de uma classe que implementa a interface A.
Mecanismo de implementação de polimorfismo Java
O atual mecanismo de implementação da JVM da Sun, a referência de uma instância de classe é um ponteiro para uma alça, que é um par de indicadores:
Um ponteiro aponta para uma tabela e, de fato, esta tabela também possui dois ponteiros (um ponteiro aponta para uma tabela de métodos que contém o objeto e o outro ponteiro para um objeto de classe, indicando o tipo ao qual o objeto pertence);
Outro ponteiro aponta para um espaço de memória alocado da pilha Java.
Resumir
(1) As chamadas de método dinâmico são implementadas atribuindo referências de objeto de subclasse a variáveis de referência de objeto de superclass.
DerivedC C2 = New DerivedC (); BaseClass A1 = C2; // Classe base Baseclass, Derivedc é A1.Play () herdado de Baseclass; //play() is defined in BaseClass and DerivedC, that is, the subclass overrides the method
analisar:
* 为什么子类的类型的对象实例可以覆给超类引用?
自动实现向上转型。通过该语句,编译器自动将子类实例向上移动,成为通用类型BaseClass;
* a.play()将执行子类还是父类定义的方法?
子类的。在运行时期,将根据a这个对象引用实际的类型来获取对应的方法。所以才有多态性。一个基类的对象引用,被赋予不同的子类对象引用,执行该方法时,将表现出不同的行为。
在a1=c2的时候,仍然是存在两个句柄,a1和c2,但是a1和c2拥有同一块数据内存块和不同的函数表。
(2)不能把父类对象引用赋给子类对象引用变量
BaseClass a2=new BaseClass(); DerivedC c1=a2;//出错
在java里面,向上转型是自动进行的,但是向下转型却不是,需要我们自己定义强制进行。
c1=(DerivedC)a2; 进行强制转化,也就是向下转型.
(3)记住一个很简单又很复杂的规则,一个类型引用只能引用引用类型自身含有的方法和变量。
你可能说这个规则不对的,因为父类引用指向子类对象的时候,最后执行的是子类的方法的。
其实这并不矛盾,那是因为采用了后期绑定,动态运行的时候又根据型别去调用了子类的方法。而假若子类的这个方法在父类中并没有定义,则会出错。
例如,DerivedC类在继承BaseClass中定义的函数外,还增加了几个函数(例如myFun())
analisar:
当你使用父类引用指向子类的时候,其实jvm已经使用了编译器产生的类型信息调整转换了。
这里你可以这样理解,相当于把不是父类中含有的函数从虚拟函数表中设置为不可见的。注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。
(4)Java与C++多态性的比较
jvm关于多态性支持解决方法是和c++中几乎一样的,
只是c++中编译器很多是把类型信息和虚拟函数信息都放在一个虚拟函数表中,但是利用某种技术来区别。
Java把类型信息和函数信息分开放。Java中在继承以后,子类会重新设置自己的虚拟函数表,这个虚拟函数表中的项目有由两部分组成。从父类继承的虚拟函数和子类自己的虚拟函数。
虚拟函数调用是经过虚拟函数表间接调用的,所以才得以实现多态的。
Java的所有函数,除了被声明为final的,都是用后期绑定。
1个行为,不同的对象,他们具体体现出来的方式不一样,
比如: 方法重载overloading 以及方法重写(覆盖)override
class Human{ void run(){输出人在跑} } class Man extends Human{ void run(){输出男人在跑} } 这个时候,同是跑,不同的对象,不一样(这个是方法覆盖的例子) class Test{ void out(String str){输出str} void out(int i){输出i} }这个例子是方法重载,方法名相同,参数表不同
ok,明白了这些还不够,还用人在跑举例
Human ahuman=new Man();
这样我等于实例化了一个Man的对象,并声明了一个Human的引用,让它去指向Man这个对象意思是说,把Man这个对象当Human看了.
比如去动物园,你看见了一个动物,不知道它是什么, "这是什么动物? " "这是大熊猫! "
这2句话,就是最好的证明,因为不知道它是大熊猫,但知道它的父类是动物,所以,
这个大熊猫对象,你把它当成其父类动物看,这样子合情合理.
这种方式下要注意new Man();的确实例化了Man对象,所以ahuman.run()这个方法输出的是"男人在跑"
如果在子类Man下你写了一些它独有的方法比如eat(),而Human没有这个方法,
在调用eat方法时,一定要注意强制类型转换((Man)ahuman).eat(),这样才可以...
对接口来说,情况是类似的...
Exemplo:
package domain; //Define superA class superA { int i = 100; void fun(int j) { j = i; System.out.println("This is superA"); } } //Define superA subclass subB class subB extends superA { int m = 1; void fun(int aa) { System.out.println("This is subB"); } } //Define superA subC class subC extends superA { int n = 1; void fun(int cc) { System.out.println("This is subB"); } } //Define superA subC class subC extends superA { int n = 1; void fun(int cc) { System.out.println("This is subC"); } } class Test { public static void main(String[] args) { superA a = new superA(); subB b = new subB(); subC c = new subC(); a = b; a.fun(100); a = c; a.fun(200); }} /*
* 上述代码中subB和subC是超类superA的子类,我们在类Test中声明了3个引用变量a, b,
* c,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。也许有人会问:
* "为什么(1)和(2)不输出:This is superA"。
* java的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,
* 被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,
* 但是这个被调用的方法必须是在超类中定义过的,
* 也就是说被子类覆盖的方法。
* 所以,不要被上例中(1)和(2)所迷惑,虽然写成a.fun(),但是由于(1)中的a被b赋值,
* 指向了子类subB的一个实例,因而(1)所调用的fun()实际上是子类subB的成员方法fun(),
* 它覆盖了超类superA的成员方法fun();同样(2)调用的是子类subC的成员方法fun()。
* 另外,如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,
* 但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性。具体的实现方法同上例。
* 不过,抽象类的子类必须覆盖实现超类中的所有的抽象方法,
* 否则子类必须被abstract修饰符修饰,当然也就不能被实例化了
*/
以上大多数是以子类覆盖父类的方法实现多态.下面是另一种实现多态的方法-----------重写父类方法
JAVA里没有多继承,一个类之能有一个父类。而继承的表现就是多态。一个父类可以有多个子类,而在子类里可以重写父类的方法(例如方法print()),这样每个子类里重写的代码不一样,自然表现形式就不一样。这样用父类的变量去引用不同的子类,在调用这个相同的方法print()的时候得到的结果和表现形式就不一样了,这就是多态,相同的消息(也就是调用相同的方法)会有不同的结果。举例说明:
//Premary class public class Father{ //The parent class has a method to hit the child public void hitChild(){ } } //Subclass 1 public class Son1 extends Father{ //Rewrite the method to hit the child public void hitChild(){ System.out.println("Why hit me? What I did wrong!"); } } //Subclass 2 public class Son2 extends Father{ //Rewrite the method to hit the child public void hitChild(){ System.out.println("I know I'm wrong, stop hitting it!"); } } //Subclass 3 public class Son3 extends Father{ //Rewrite the parent class hits the child method public void hitChild(){ System.out.println("I run, you can't hit!"); } } //Test class public class Test{ public static void main(String args[]){ Father father; father = new Son1(); father.hitChild(); father = new Son2(); father.hitChild(); father = new Son3(); father.hitChild(); }}都调用了相同的方法,出现了不同的结果!这就是多态的表现!
import java.io.*;class Super{ Super(){ System.out.println("This is super class!"); } void method(){ System.out.println("Super's method"); }}class Sub extends Super{ Sub(){ super(); System.out.println("/n/t:and here is the child"); } void method(){ System.out.println("child's method"); }}public class Super_Sub{ public static void main(String[] args){ Super sup=new Sub(); sup.method(); Sub child=(Sub)new Super();//Here, the actual allocated memory is Super, but Child is used to refer to it. This is "downward transformation" (the parent class impersonates a child class, because the subclass is down when drawing in UML), and it must be casted by child.method(); }}对于数据来说,继承是否为正确的设计可以用一个简单的规则来判断。“is-a”规则表明子类的每一个对象都是一个超类的对象。例如,每一个经理是一个员工。然而,只有经理类是员工类的子类才是有意义的。很明显,反过来就不行了――并不是每个员工都是经理。
还有一个明确叙述“is-a”规则的方法是替代原则。该原则规定无论何时,如果程序需要一个超类对象,都可以用一个子类对象来代替
动态绑定
理解调用一个对象方法的机制是非常重要的。下面具体介绍:Xf;
(1)编译器检查对象的声明类型和方法名。
(2) Next, the compiler checks the parameter type in the method call. If one of all methods called f has a parameter type whose parameter type best matches the parameter type provided by the call, the method will be selected to call. This process is called overload selection. (estático)
(3)当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用同x所指向的对象的实际类型相匹配的方法版本。
……
如果类中没有写构造函数,那么系统会自动为该类提供一个默认构造函数,该构造函数将所有的实例字段初始化为默认值:
……
包用途:
Java允许把多个类收集在一起成为一组,称作包(package)。包便于组织任务,以及使自己的任务和其他人提供的代码库相分离。
标准Java库被分类成许多的包,其中包括java.1ang、java.util和java.net等等。标准Java包是分层次的。就像在硬盘上嵌套有各级子目录一样,可以通过层次嵌套组织包。所有的Java包都在Java和Javax包层次内
创建包
已经看到,已有的库,比如JavaAPI中的类和接口,可以导入到Java程序中。
Java API中的每一个类和接口属于一个特定的包。它包含一组相关联的类和接口,实际是对类和接口进行组织的目录结构。
例如,假定文件名是MyClass.java。它意味着在那个文件有一个、而且只能有一个public类。而且那个类的名字必须是MyClass(包括大小写形式):
packagemypackage;publicclass MyClass{……}创建可复用的类的步骤简要说明如下:
(1)定义一个public类。如果类不是public,它只能被同一包中的其他类使用。
(2)选择一个包名,并把package语句加到可复用的类的源代码文件中。
(3)编译这个类。这样,它就被放到适当的包目录结构中,以供编译器和解译器使用。
(4)把这个可复用的类导入到需要用它的程序中。现在就可以使用它了。
注意在Java语言中可以出现在类定义的括号外面的仅有两个语句,它们是package和import。
包引用---每个类名前加上完整的包名
例如,给出一个指向此包中的类的快捷方式。一旦使用import(导入)了以后,就不再需要给出完整的包名。
可以引入一个特定的类,也可以引入整个包。import语句要放在源文件的头部(但在所有package语句的下面)。例如,可以通过下面的语句引入在java.util包中的所有的类:
importjava.util.*;
然后,就可以使用
Datetoday=new Date();
而不需要在前面加上包名。也可以引入包中某个特定的类:
importjava.util.Date;
要把类放人一个包中,必须把此包的名字放在源文件头部,并且放在对包中的类进行定义的代码之前。例如,在文件Employee.java的开始部分如下:
packagecom.horstmann.corejava;publicclass Employee{……}把包中的文件放入与此完整的包名相匹配的子目录中。例如,在包com.horstmann.corejava中的所有的类文件都必须放在子目录com/horstmann/core.java(Windows下的com/horstmann/corejava)下。这是最简单的一种方法
类被存储在文件系统的子目录中。类的路径必须与所在包名相匹配。
在前面的例子中,包目录com/horstmann/corejava是程序目录的一个子目录。然而这样安排很不灵活。一般,有多个程序需要访问包文件。为了使包可以在多个程序间共享,需要做以下事情:
1)把类放在一个或多个特定的目录中,比如/home/user/classdir。此目录是包树的基本目录。如果加入了类com.horstmann.corejava.Employee,那么此类文件必须位于子目录/home/user/classdir/com/horstmann/corejava下。
2)设置类路径。类路径是其子目录包含类文件的所有基本目录的集合。classpath
已经接触过public和private访问指示符。
被标记为Public的部件可以被任何类使用,而私有部件只能被定义它们的类使用。如果没有指定public或private,那么部件(即类、方法或变量)可以被同一个包中的所有方法访问。
Java API包
为了简化面向对象的编程过程,Java系统事先设计并实现了一些体现了常用功能的标准类,如用于输入/输出的类,用于数学运算的类,用于图形用户界面设计的类,用于网络处理的类等。这些系统标准类根据实现的功能不同,可以划分成不同的集合,每个集合是一个包,合称为类库。可以引用这些包,也可以创建自己的包。
Java的类库是系统提供的已实现的标准类的集合,是Java编程的API,它可以帮助开发者方便、快捷地开发Java程序
接口主要作用是可以帮助实现类似于类的多重继承的功能。在Java中,出于简化程序结构的考虑,不再支持类间的多重继承而只支持单重继承,即一个类至多只能有一个直接父类。然而在解决实际问题的过程中,仅仅依靠单重继承在很多情况下都不能将问题的复杂性表述完整,需要其他的机制作为辅助。
接口声明
Java中声明接口的语法如下:
[public] interface 接口名[extends 父接口名列表]{ //接口体;//常量域声明[public] [static] [final] 域类型域名=常量值; //抽象方法声明[public] [abstract] 返回值方法名(参数列表) [throw异常列表];}从上面的语法规定可以看出,定义接口与定义类非常相似,实际上完全可以把接口理解成为一种特殊的类,接口是由常量和抽象方法组成的特殊类
(1)接口中的属性都是用final修饰的常量,
(2)接口中的方法都是用abstract修饰的抽象方法,在接口中只能给出这些抽象方法的方法名、返回值和参数列表,而不能定义方法体,即仅仅规定了一组信息交换、传输和处理的“接口”
接口的实现
一个类要实现某个或某几个接口时,有如下的步骤和注意事项:
(1)在类的声明部分,用implements关键字声明该类将要实现哪些接口;
do seguinte modo:
class类名implements接口{ }(2)如果实现某接口的类不是abstract的抽象类,则在类的定义部分必须实现指定接口的所有抽象方法,即为所有抽象方法定义方法体,而且方法头部分应该与接口中的定义完全一致,即有完全相同的返回值和参数列表;
(3)如果实现某接口的类是abstract的抽象类,则它可以不实现该接口所有的方法。
(4)一个类在实现某接口的抽象方法时,必须使用完全相同的方法头。
(5)接口的抽象方法,其访问限制符都已指定是public,所以类在实现方法时,必须显式地使用public修饰符。
resumo:
多重继承是指一个子类继承多个父类。Java不支持多重继承,但Java提供了接口。
子类不能访问父类的private成员,但子类可以访问其父类的public,protected和包访问成员;要访问父类的包访问成员,子类一定要在父类的包内。
子类构造函数总是先调用(显式的或隐式地)其父类的构造函数,以创建和初始化子类的父类成员。
子类的对象可以当作其父类的对象对待,反之则不行(即向上转型)
protected访问是public和private访问之间一个保护性的中间层次。父类方法、子类方法和在同一个包内类的方法都能访问父类的protected成员,但其他方法均不能访问
一个子类对象引用可以隐式地转换成一个父类对象引用。使用显式的类型转换,可以把父类引用转换成子类引用。如果目标不是子类对象,将产生ClassCastException例外处理。