我对这个Java代码有些怀疑.它给出的输出是"毛茸茸的bray".我的问题:
class Mammal {
String name = "furry ";
String makeNoise() { return "generic noise"; }
}
class Zebra extends Mammal {
String name = "stripes ";
String makeNoise() { return "bray"; }
}
public class ZooKeeper {
public static void main(String[] args) { new ZooKeeper().go(); }
void go() {
Mammal m = new Zebra();
System.out.println(m.name + m.makeNoise());
//Output comes as "furry bray". Please explain this.
//And how can we access the name variable, the one …Run Code Online (Sandbox Code Playgroud) 我无法理解以下输出.
我不知道为什么输出是10,我认为该行A a = new B()创建了一个B类的新实例,我认为结果应该是20
class A {
int i = 10;
}
class B extends A {
int i = 20;
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i);
}
}
Run Code Online (Sandbox Code Playgroud)
为什么这样工作..请解释.
因此,当我遇到这个 - 对我来说 - 奇怪的现象时,我正在测试一些代码片段来围绕继承的概念.
所以首先我测试这个简单的代码:
public class Main{
public static void main(String[] args) {
Bar bar = new Bar();
System.out.println("age = " + bar.age);
bar.test();
}
}
class Foo{
int age = 2;
void test(){
System.out.println("TEST FOO");
}
}
class Bar extends Foo{
int age = 4;
void test(){
System.out.println("TEST BAR");
}
}
Run Code Online (Sandbox Code Playgroud)
输出就像我预期的那样:
age = 4
TEST BAR
Run Code Online (Sandbox Code Playgroud)
然后我做了一个小的变化,以3行,其中我改变的类型Bar,以Foo这样的:
Foo bar = new Bar();
Run Code Online (Sandbox Code Playgroud)
现在当我运行代码时,它给了我一个输出我相信很奇怪:
age = 2
TEST BAR
Run Code Online (Sandbox Code Playgroud)
bar.age现在代码是如何使用类的age成员 …
我想知道为什么Java对于超类和具有相同名称的实例变量的子类有这种奇怪的行为.
假设我们有以下类定义:
class Parent {
int var = 1;
}
class Child extends Parent {
int var = 2;
}
Run Code Online (Sandbox Code Playgroud)
通过这样做,我们应该隐藏超类的变量var.如果我们没有明确指定的方式来访问Parent的var通过super电话,那么我们不应该能够访问var一个孩子的一个实例.
但是当我们有一个演员表时,这个隐藏机制就会破坏:
Child child = new Child();
Parent parent = (Parent)child;
System.out.println(parent.var); // prints out 1, instead of 2
Run Code Online (Sandbox Code Playgroud)
这不完全绕过整个隐藏点吗?如果是这种情况,那么这不会使这个想法完全没用吗?
编辑:我在Java教程中专门提到这篇文章.它提到了
在子类中,超类中的字段不能通过其简单名称引用.相反,必须通过超级...访问该字段
从我在那里读到的内容,似乎暗示Java的开发人员在这方面考虑了某种技术.虽然我同意这是一个相当模糊的概念,但总的来说可能是不好的做法.
我今天正在尝试匿名课程.当我这样做时System.out.println(super.x);,它打印12,当我使用System.out.println(x);它打印4.我认为super.x会打印4,并想知道是否有人可以请你解释为什么这是?
public class AnonClass {
private int x = 1;
public AnonClass(int x) {
this.x = x;
}
public static void main(String[] args) {
AnonClass test = new AnonClass(4);
test.testMethod();
}
public void testMethod() {
AnonClass anon = new AnonClass(12) {
{
System.out.println(super.x); //Prints 12
System.out.println(x); //prints 4
}
};
}
}
Run Code Online (Sandbox Code Playgroud) package one;
public class A {
protected int first;
protected static int second;
}
Run Code Online (Sandbox Code Playgroud)
package two;
import one.A;
public class B extends A {
public void someMethod() {
this.first = 5; //works as expected
B.second = 6; //works
A a = new A();
// a.first = 7; does not compile
//works just fine, but why?
a.second = 8;
A.second = 9;
}
}
Run Code Online (Sandbox Code Playgroud)
为什么不对静态字段应用相同的限制,它背后的想法是什么?
在 Kotlin 中使用类委托时,您可以覆盖成员。然而,关于授权的参考页说:
但请注意,以这种方式重写的成员不会从委托对象的成员中调用,委托对象只能访问其自己的接口成员实现。
我想重写委托对象的方法使用的属性,以便委托对象的方法调用此重写的属性。正如文档所述,使用关键字覆盖属性并override不能实现此目的。有没有办法可以实现这种行为?如果不是,这是否表明我应该使用继承?
这是一个代码示例:
interface Base {
val message: String
fun print()
}
class BaseImpl(val x: Int) : Base {
override val message = "BaseImpl: x = $x"
override fun print() { println(message) }
}
class Derived(b: Base) : Base by b {
// This property is not accessed from b's implementation of `print`
override val message = "Message of Derived"
}
fun main(args: Array<String>) {
val b = BaseImpl(10)
val derived = Derived(b) …Run Code Online (Sandbox Code Playgroud) 这是我写的三个类:
public class Shape {
public int x = 0;
public void getArea() {
System.out.println("I don't know my area!");
}
public String toString() {
return "I am a shape!";
}
public int getX() {
return x;
}
}
public class Rectangle extends Shape {
public int x = 1;
public int getX() {
return x;
}
public void getArea() {
System.out.println("L*W");
}
public String toString() {
return "I am a rectangle!";
}
}
public class Tester {
public static void …Run Code Online (Sandbox Code Playgroud) 我需要一个将在子类中使用的类中的方法,尽管该方法使用的是在子类中更改的属性。有没有一种方法可以访问子类的属性而不必重写该方法?
我已经尝试过使用该属性的吸气剂,但得到相同的结果。
public class SuperClass {
private static final String a = "Super";
public void superMethod(){
System.out.println("SuperMethod: " + a);
}
}
public class ChildClass extends SuperClass {
private static final String a = "Child";
}
public class Main {
public static void main(String[] args) {
SuperClass s = new SuperClass();
ChildClass c = new ChildClass();
s.superMethod();
c.superMethod();
}
}
Run Code Online (Sandbox Code Playgroud)
控制台显示:
超级方法:超级
超级方法:超级
预期结果是:
超级方法:超级
超级方法:子级
java ×8
inheritance ×2
class ×1
instance ×1
kotlin ×1
member ×1
oop ×1
overriding ×1
polymorphism ×1
variables ×1