Esta é uma pergunta de entrevista.
As subclasses herdam campos particulares?
Respondi "Não", porque não podemos acessá-los usando o "modo normal de POO". Mas o entrevistador pensa que eles são herdados, porque podemos acessar esses campos indiretamente ou usando a reflexão e eles ainda existem no objeto.
Depois que voltei, encontrei a seguinte citação no javadoc :
Membros privados em uma superclasse
Uma subclasse não herda os membros privados de sua classe pai.
Você conhece algum argumento para a opinião do entrevistador?
java
oop
inheritance
private
Stan Kurilin
fonte
fonte
Respostas:
A maior parte da confusão nas perguntas / respostas aqui envolve a definição de herança.
Obviamente, como o @DigitalRoss explica, um OBJETO de uma subclasse deve conter os campos privados de sua superclasse. Como ele afirma, não ter acesso a um membro privado não significa que não existe.
Contudo. Isso é diferente da noção de herança para uma classe. Como é o caso no mundo java, onde há uma questão de semântica, o árbitro é a Java Language Specification (atualmente na 3ª edição).
Como o JLS declara ( https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2 ):
Isso aborda a pergunta exata feita pelo entrevistador: "as sub CLASSES herdam campos privados". (ênfase adicionada por mim)
A resposta é não. Eles não. OBJETOS de subclasses contêm campos particulares de suas superclasses. A subclasse em si não tem NOTION de campos particulares de sua superclasse.
É semântica de natureza pedante? Sim. É uma pergunta de entrevista útil? Provavelmente não. Mas o JLS estabelece a definição para o mundo Java e o faz (neste caso) sem ambiguidade.
EDITADO (removida uma citação paralela de Bjarne Stroustrup que, devido às diferenças entre java e c ++, provavelmente apenas aumenta a confusão. Vou deixar minha resposta no JLS :)
fonte
sim
É importante perceber que, enquanto não são duas classes, há apenas um objeto.
Então, sim, é claro que herdou os campos particulares. Eles são, presumivelmente, essenciais para a funcionalidade apropriada do objeto e, embora um objeto da classe pai não seja um objeto da classe derivada, uma instância da classe derivada é definitivamente uma instância da classe pai. Não poderia muito bem ser isso sem todos os campos.
Não, você não pode acessá-los diretamente. Sim, eles são herdados. Eles têm que ser.
É uma boa pergunta!
Atualizar:
Err, "Não"
Bem, acho que todos aprendemos alguma coisa. Como o JLS originou a expressão exata "não herdada", é correto responder "não" . Como a subclasse não pode acessar ou modificar os campos particulares, em outras palavras, eles não são herdados. Mas, na verdade, existe apenas um objeto, ele realmente contém os campos privados; portanto, se alguém usar o JLS e o tutorial de maneira errada, será muito difícil entender OOP, objetos Java e o que realmente está acontecendo.
Atualize para atualizar:
A controvérsia aqui envolve uma ambiguidade fundamental: o que exatamente está sendo discutido? O objeto? Ou estamos falando de algum modo sobre a própria classe? Muita latitude é permitida ao descrever a classe em oposição ao objeto. Portanto, a subclasse não herda campos privados, mas um objeto que é uma instância da subclasse certamente contém os campos privados.
fonte
car
, ele o guardava em umprivate
armário que a criança não tem a chave. Você de fato herda ocar
mas é inútil para você. Então, praticamente, você não está se beneficiando da herança.Não. Os campos particulares não são herdados ... e é por isso que Protected foi inventado. É por design. Eu acho que isso justificou a existência de modificador protegido.
Agora chegando aos contextos. O que você quer dizer com herdado - se ele existe no objeto criado a partir da classe derivada? Sim, ele é.
Se você quer dizer, pode ser útil para a classe derivada. Bem não.
Agora, quando você chega à programação funcional, o campo privado da superclasse não é herdado de maneira significativa para a subclasse . Para a subclasse, um campo privado de superclasse é igual a um campo privado de qualquer outra classe.
Funcionalmente, não é herdado. Mas , idealmente , é.
OK, apenas olhei para o tutorial Java, eles citam isso:
consulte: http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html
Eu concordo que o campo está lá. Porém, a subclasse não recebe nenhum privilégio nesse campo privado. Para uma subclasse, o campo privado é o mesmo que qualquer campo particular de qualquer outra classe.
Eu acredito que é puramente questão de ponto de vista. Você pode moldar o argumento de ambos os lados. É melhor justificar para os dois lados.
fonte
I believe it's purely matter of point-of-view.
ejustified the existence of protected modifier.
Depende da sua definição de "herdar". A subclasse ainda possui os campos na memória? Definitivamente. Pode acessá-los diretamente? Não. São apenas sutilezas da definição; o objetivo é entender o que realmente está acontecendo.
fonte
Vou demonstrar o conceito com código. Subclasses REALMENTE herdam as variáveis privadas da super classe. O único problema é que eles não são acessíveis aos objetos filhos, a menos que você forneça getters e setters públicos para as variáveis privadas na superclasse.
Considere duas classes no pacote Dump. Filho estende Pai.
Se bem me lembro, um objeto filho na memória consiste em duas regiões. Um é apenas a parte pai e o outro é apenas a parte filho. Um filho pode acessar a seção privada no código de seu pai apenas através de um método público no pai.
Pense desta maneira. O pai de Borat, Boltok, tem um cofre contendo US $ 100.000. Ele não quer compartilhar seu cofre "variável" privado. Então, ele não fornece uma chave para o cofre. Borat herda o cofre. Mas, de que adianta ele nem conseguir abri-lo? Se ao menos o pai dele tivesse fornecido a chave.
Pai -
Criança -
fonte
Não. Eles não herdam.
O fato de alguma outra classe usá-lo indiretamente não diz nada sobre herança, mas sobre encapsulamento.
Por exemplo:
Você também pode obter o valor de
count
dentroUseIt
via reflexão. Isso não significa que você herda.ATUALIZAR
Mesmo que o valor esteja lá, ele não é herdado pela subclasse.
Por exemplo, uma subclasse definida como:
Essa é exatamente a mesma situação do primeiro exemplo. O atributo
count
está oculto e não é herdado pela subclasse. Ainda assim, como DigitalRoss aponta, o valor está lá, mas não por meio de herança.Põe desta forma. Se seu pai é rico e lhe dá um cartão de crédito, você ainda pode comprar coisas com o dinheiro dele, mas não significa que você herdou todo esse dinheiro, não é?
Outra atualização
É muito interessante saber por que o atributo está lá.
Francamente, não tenho o termo exato para descrevê-lo, mas é a JVM e a maneira como funciona que carrega também a definição de pai "não herdada".
Poderíamos realmente mudar o pai e a subclasse ainda funcionará.
Por exemplo :
Acho que o termo exato pode ser encontrado aqui: The JavaTM Virtual Machine Specification
fonte
encapsulation
vsinherit
, acho que essa resposta merece mais votos positivos.Bem, minha resposta para a pergunta do entrevistador é: os membros privados não são herdados das subclasses, mas são acessíveis à subclasse ou ao objeto da subclasse apenas por meio de métodos públicos getter ou setter ou por qualquer método apropriado da classe original. A prática normal é manter os membros privados e acessá-los usando métodos getter e setter que são públicos. Então, qual é o sentido de herdar apenas métodos getter e setter quando o membro privado com o qual lidam não está disponível para o objeto? Aqui 'herdado' significa simplesmente que ele está disponível diretamente na subclasse para brincar com os métodos recém-introduzidos na subclasse.
Salve o arquivo abaixo como ParentClass.java e tente você mesmo ->
Se tentarmos usar a variável privada x de ParentClass no método SubClass, ele não estará diretamente acessível para quaisquer modificações (significa não herdado). Mas x pode ser modificado na SubClasse via método setX () da classe original, como foi feito no método setXofParent () OU pode ser modificado usando o objeto ChildClass usando o método setX () ou o método setXofParent () que chama finalmente setX (). Então aqui setX () e getX () são uma espécie de porta para o membro privado x de uma ParentClass.
Outro exemplo simples é a superclasse Clock que possui horas e minutos como membros particulares e métodos getter e setter apropriados como públicos. Então vem o DigitalClock como uma subclasse de Clock. Aqui, se o objeto do DigitalClock não contiver membros horas e minutos, as coisas estão erradas.
fonte
Ok, este é um problema muito interessante. Pesquisei bastante e cheguei à conclusão de que membros privados de uma superclasse estão realmente disponíveis (mas não acessíveis) nos objetos da subclasse. Para provar isso, aqui está um código de exemplo com uma classe pai e uma classe filho. Estou escrevendo um objeto de classe filho em um arquivo txt e lendo um membro privado chamado 'bhavesh' no arquivo, provando que ele está realmente disponível no filho classe, mas não acessível devido ao modificador de acesso.
Abra MyData1.txt e procure o membro particular chamado 'bhavesh'. Por favor me digam o que vocês acham.
fonte
Parece que uma subclasse herda os campos privados, pois esses mesmos campos são utilizados no funcionamento interno da subclasse (filosoficamente falando). Uma subclasse, em seu construtor, chama o construtor da superclasse. Os campos privados da superclasse são obviamente herdados pela subclasse que chama o construtor da superclasse se o construtor da superclasse inicializou esses campos em seu construtor. Isso é apenas um exemplo. Mas é claro que sem os métodos de acesso, a subclasse não pode acessar os campos particulares da superclasse (é como não ser capaz de abrir o painel traseiro de um iPhone para tirar a bateria e reiniciar o telefone ... mas a bateria ainda está lá).
PS Uma das muitas definições de herança que encontrei: "Herança - uma técnica de programação que permite que uma classe derivada estenda a funcionalidade de uma classe base, herdando todo o seu ESTADO (ênfase é minha) e comportamento".
Os campos particulares, mesmo que não sejam acessíveis pela subclasse, são o estado herdado da superclasse.
fonte
Eu teria que responder que os campos privados em Java são herdados. Permita-me demonstrar:
Se você executar um programa
Bar bar = new Bar();
, sempre verá o número "2" na caixa de saída. Como o número inteiro "x" é encapsulado com os métodosupdate()
egetX()
, é possível provar que o número inteiro é herdado.A confusão é que, como você não pode acessar diretamente o número inteiro "x", as pessoas argumentam que ele não é herdado. No entanto, todas as coisas não estáticas em uma classe, seja campo ou método, são herdadas.
fonte
Os bits de preenchimento / alinhamento e a inclusão da classe de objeto no VTABLE não são considerados. Portanto, o objeto da subclasse tem um lugar para os membros privados da classe Super. No entanto, ele não pode ser acessado a partir dos objetos da subclasse ...
fonte
Não , campos privados não são herdados. A única razão é que a subclasse não pode acessá-los diretamente .
fonte
Creio que a resposta depende totalmente da pergunta que foi feita. Quero dizer, se a pergunta for
Então a resposta é Não . Se formos examinados os detalhes do especificador de acesso , é mencionado que membros privados são acessíveis apenas dentro da própria classe.
Mas, se a pergunta for
O que significa, não importa, o que você fará para acessar o membro privado. Nesse caso, podemos tornar o método público na superclasse e você pode acessar o membro privado. Portanto, neste caso, você está criando uma interface / ponte para acessar o membro privado.
Outras linguagens de POO, como C ++, têm o
friend function
conceito pelo qual podemos acessar o membro privado de outra classe.fonte
Podemos simplesmente afirmar que, quando uma superclasse é herdada, os membros privados da superclasse tornam-se membros privados da subclasse e não podem mais ser herdados ou são inacessíveis aos objetos da subclasse.
fonte
Um membro ou construtor de classe privada é acessível apenas dentro do corpo da classe de nível superior ( §7.6 ) que inclui a declaração do membro ou construtor. Não é herdado por subclasses. https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6
fonte
Uma subclasse não herda os membros privados de sua classe pai. No entanto, se a superclasse tiver métodos públicos ou protegidos para acessar seus campos particulares, eles também poderão ser usados pela subclasse.
fonte
Membros privados (estado e comportamento) são herdados. Eles podem afetar o comportamento e o tamanho do objeto instanciado pela classe. Sem mencionar que eles são muito bem visíveis para as subclasses através de todos os mecanismos de quebra de encapulação disponíveis ou podem ser assumidos por seus implementadores.
Embora a herança tenha uma definição "defacto", ela definitivamente não tem vínculo com os aspectos de "visibilidade", que são assumidos pelas respostas "não".
Portanto, não há necessidade de ser diplomático. JLS está errado neste momento.
Qualquer suposição de que eles não sejam "herdados" é insegura e perigosa.
Assim, entre duas definições defacto (parcialmente) conflitantes (que não repetirei), a única que deve ser seguida é a mais segura (ou segura).
fonte