Question about dynamic typing in Java
I got this from a berkley cs data structures webcast:
class A {
void f() {System.out.println("A.f");}
void g() {f();}
// static void g(A y) {y.f();}
}
class B extends A {
void f(){
System.out.println("B.f");
}
}
class C {
static void main (String[] args){
B aB = new B();
h (aB);
}
static void h (A x) {x.g();}
//static void h (A x) {A.g(x);} what if this were h
}
Can you tell me what prints out and why? The instructor said B.f but I do not understand why. I thought it was A.f. Thank you (no, I am not in the class, just trying to learn.)
edit: sorry 开发者_JS百科for the mistakes I was copying it from a video lecture.
This example demonstrates the power of object-oriented programming.
Because ab is an instance of B, any method call on ab will use the functions defined in B, even if these functions are called indirectly via a function defined in a superclass.
The example is so abstract that the virtue of this may not be clear. Let me make a slightly more realistic example:
class Employee
{
... bunch of stuff ...
void calcPay()
{
pay=hoursWorked*hourlyRate;
}
void produceCheck))
{
calcPay();
calcTaxes();
calcBenefitDeductions();
printCheck();
}
}
class Salesman extends Employee
{
void calcPay()
{
pay=sales*commissionRate;
}
}
... somewhere else ...
for (Employee employee1 : employeeList)
{
employee1.produceCheck();
}
I'm leaving out all sorts of detail to make the point: This code won't compile.
But here's the point: Salesman have a different method of calculating their pay then other employees: They're paid on commission instead of hourly. (In real life, we'd presumably also have salaried employees, but as I say, I'm simplifying.) The function to calculate pay of either type of employee is called from within a bigger function that also does other things. The beauty of object-oriented programming is that we can call the outside function and not care whether the object we are calling it against is a regular Employee or a Salesman. Each object knows what it is and calls the right function. In the last few lines of the example, we have some structure that includes both regular Employees and Salesmen, and we can loop through and process them all without having to check their type. Without OOP, we'd have to constantly write code like: "if (type == SALESMAN) ... else if (type == HOURLY) ..."
The reason "B.f" prints is because the implementation of a method is determined by an object's run-time type, not its compile-time type. It's like the virtual
keyword in C++.
Once you construct a B
, you know that calling its f
method will print "B.f", even if the B
is being referred to as an A
.
Also, your A.f
method is missing a close brace.
that code is not correct, A.g() does not take any arguments.
static void h (A x) {A.g(x);}
A.g(x); is trying to call a static method on A called g with x as an argument. That is not possible with the code example you posted.
other than the wrong code, the reason is B overrides the method f() with its own implementation. Thus any instances of B such as B x = new B(); will call the f() that B defines not the A.f(). The only way to reach the A.f() would be from inside an instance of B by calling super.f();
精彩评论