but I've been programming in Java so I know you can Override methods in Object's instantiation
private MyObject myObject=new MyObject(){
#Override
public void myMethod(int args){
.
.
.
}
}
can somebody show me how to do this in C# please.. Thanks
Unlike Java where all instance methods a virtual ones, in C# you have to put virtual keyword explicitly:
public class MyObject {
...
// in order to be overriden in a derived class, base method should be
// explictly declared as virtual or abstract
public virtual void myMethod(int args){
...
}
...
}
In C# override is a keyword as well, not just an attribute:
// class can't be declared locally, but explictly
public class MyOverridenObject: MyObject {
...
// override is a mandatory keyword in the context
public override void myMethod(int args){
...
}
}
Finally, C# doesn't allow implementing classes locally, so you have to declare the class explicitly (MyOverridenObject in the code above) and then use:
// Finally, you can assign an overriden class to the private field
private MyObject myObject = new MyOverridenObject();
so I know you can Override methods in Object's declaration
This isn't object declaration but class instantiation. And this feature doesn't exist in C# .
Therefore, you can only override polymorphic methods on class declarations:
public class A
{
public virtual void DoStuff() {}
}
public class B : A
{
public override void DoStuff() {}
}
Related
public class Base {
public Base() {
foo();
}
public void foo() {
System.out.println("Base.foo()");
}
}
public class Derived extends Base {
public Derived () {}
public void foo() {
System.out.println("Derived.foo()");
}
}
And then, when i call those:
public class Running {
public static void main(String[] args) {
Base b = new Base();
Derived d = new Derived();
}
}
It outputs:
*Base.foo()*
*Derived.foo()*
So why, when it gets to derived constructor, it invokes the base constructor but uses the derived's method instead?
PS: If I mark those methods as private, it will print out:
*Base.foo()*
*Base.foo()*
This is how Java works read this page https://docs.oracle.com/javase/tutorial/java/IandI/super.html
And more specifically the Note here :
Note: If a constructor does not explicitly invoke a superclass
constructor, the Java compiler automatically inserts a call to the
no-argument constructor of the superclass. If the super class does not
have a no-argument constructor, you will get a compile-time error.
Object does have such a constructor, so if Object is the only
superclass, there is no problem.
So as you can see this is expected behavior. Even though you dot have a super call it is still automatically inserting it.
In regards of the second Question even though you are within the super constructor body still you Instance is of the Subtype. Also if you have some familiarity with C++ read this Can you write virtual functions / methods in Java?
The reason why it will write the base class when marking with private is because private methods are not Inherited. This is part of the Inheritance in Java topic.
To answer the question in your title. As I said, you cannot avoid the base class constructor being called (or one of the base class constructors if it has more than one). You can of course easily avoid the body of the constructor being executed. For example like this:
public class Base {
public Base(boolean executeConstructorBody) {
if (executeConstructorBody) {
foo();
}
}
public void foo() {
System.out.println("Base.foo()");
}
}
public class Derived extends Base {
public Derived() {
super(false);
}
public void foo() {
System.out.println("Derived.foo()");
}
}
public class Running {
public static void main(String[] args) {
Base b = new Base(true);
Derived d = new Derived();
}
}
Now the main method prints only:
Base.foo()
Because in the contructor of the Derived class it automatically gets injected a call to super(), if you do not add a call to super or to other constructor in the same class (using this).
MyInterface.java
publc interface MyInterface{
void print();
}
Abc.java
public Class Abc implements MyInterface{
public void print(){
System.out.print("Inside Abc");
}
}
Xyz.java
public Class Xyz implements MyInterface{
public void print(){
System.out.print("Inside Xyz");
}
}
Main.java
public Class Main{
public static void main(String arg[]){
String classPath="Abc"; // this String will get assign # runtime.
Class<?> s = Class.forName(classPath);
}
}
Here inside main method classPath is "Abc", so i'm expecting Abc Instance.
The classsPath string will be Abc or Xyz or any Class Name that implements MyInterface.So depending the classPath String i want the instance of that class. like if ClassPath is "Abc" then Abc Class instance, ClassPath is "Xyz" then Xyz Class instance.
How can i achieve this dynamically.
You need to know what constructor to call.
Assuming all your classes have a no-argument constructor and you want that one:
MyInterface instance = (MyInterface) s.newInstance();
If the constructor has a different signature, you need to supply that, for example with a single String parameter:
MyInterface instance = (MyInterface) s
.getConstructor(String.class)
.newInstance("foo");
You can create an object dynamically at runtime using the name of the class, input as a simple string. This is done using a part of the Java language called reflection.
Reflection allows old code to call new code, without needing to recompile.
If a class has a no-argument constructor, then creating an object from its package-qualified class name (for example, "java.lang.Integer") is usually done using these methods:
Class.forName
Class.newInstance
If arguments need to be passed to the constructor, then these alternatives may be used instead:
Class.getConstructor
Constructor.newInstance
The most common use of reflection is to instantiate a class whose generic type is known at design-time, but whose specific implementation class is not. See the plugin topic for an example. Other uses of reflection are rather rare, and appear mostly in special-purpose programs.
I see a few typos in your post, so let's fix those first. public and class like
public interface MyInterface {
void print();
}
public class Abc implements MyInterface {
public void print() {
System.out.print("Inside Abc");
}
}
Then you use Class.newInstance() to create an Object, check that it's the expected type with instanceof and then cast like
public static void main(String[] args) {
try {
Class<?> cls = Class.forName("Abc");
Object o = cls.newInstance();
if (o instanceof MyInterface) {
MyInterface m = (MyInterface) o;
m.print();
}
} catch (Exception e) {
e.printStackTrace();
}
}
newInstance Method of Class is used to create new Instance.
public static void main(String arg[]){
String classPath="Abc"; // this String will get assign # runtime.
Class s = Class.forName(classPath);
Object object = s.newInstance();// to create new Instance
}
I'm using Java 7 and got 3 classes:
TestSuper.java
public abstract class TestSuper {
public TestSuper() {
testMethod();
}
protected abstract void testMethod();
}
TestNull.java
public class TestNull extends TestSuper {
private String test = "Test";
public TestNull() {
super();
System.out.println(test);
}
#Override
protected void testMethod() {
System.out.println(test);
}
}
TestMain.java
public class TestMain {
public static void main(String[] args) {
new TestNull();
}
}
Output:
null
Test
Why does this happen and is there a good workaround for it?
When you call new TestNull(); you're calling the constructor of the class TestNull, which it calls the super() constructor: it contains a call to the method implemented in TestNull, where you print the String field, at this time the fields of the sub-class TestNull are not yet initialized, i.e. are null.
After the super constructor call, all the fields will be initialized, and therefore the second print actually show the new value of the (initialized) string.
The key point here is that fields of a sub-class are initialized after the instantiation of the super-classes.
A workaround? It depends on what exact behaviour you desire: maybe it makes sense to NOT call the abstract method in the super constructor (i.e. in the constructor of the TestSuper class).
According to JLS 8.1.1.1 Abstract Class
A subclass of an abstract class that is not itself abstract may be
instantiated, resulting in the execution of a constructor for the
abstract class and, Therefore, the execution of the Field Initializers
for instance variables of that class.
You are calling an overridable instance method (which also calls an instance field, in your case private String test = "Test";) in the constructor. This might cause inconsistencies since the instance is not fully constructed. This is a bad practice, so avoid it:
public TestSuper() {
testMethod();
}
Please read this thread: What's wrong with overridable method calls in constructors?
you can work around this issue by moving the call of testMethod() to a separate function
public abstract class TestSuper {
public TestSuper() { }
public void callTestMethod(){
testMethod();
}
protected abstract void testMethod();
}
then call callTestMethod() on TestNull constructor
public TestNull() {
super.callTestMethod();
System.out.println(test);
}
I have declared the following interface in Java:
public interface ITest {
void doStuff();
}
which is implemented by another few classes who overwrite the doStuff() method. I then use this interface as the type in a function:
public gonnaDoSomeStuff(ITest fun) {
fun.doStuff();
}
However, Java (and Eclipse) state that the method is undefined for type ITest. What am I doing wrong?
It turns out that the class containing my gonnaDoSomeStuff method was appended with a generic, which was being referenced instead of the actual interface.
Wrong
public class Dog<ITest> {
public gonnaDoSomeStuff(ITest fun) {
// ...
}
}
Right
public class Dog {
public gonnaDoSomeStuff(ITest fun) {
// ...
}
}
You can not access default declared method in a public class because its scope is limited. You should declared it as public for call in public class.
I am developing a webApplication based on Java EE.
I have an abstract class, in which I need to have a one-time operation (a database call).
So below in the sample code, I pasted it inside its constructor, but don't know why the constructor is not getting invoked.
Please tell me how to solve this.
public abstract class Preethi {
Preethi()
{
System.out.println("hirerew");
}
public static void main(String args[])
{
int a = 12;
if(a==0)
System.out.println("a");
if (a==12)
System.out.println("12");
}
}
You never create an instance of abstract class Preethi. Why do you expect the constructor to get called? Make a non-abstract subclass and create an instance of it and then the constructor will be called. main is static, it can be called without Preethi being realized.
public class X extends Preethi
{ /* Your implementation here */}
Then in main:
public static void main(String [] args)
{
Preethi preethi = new X(); // This will call the constructor of Preethi
}
Constructor is not being invoked because main() method is called without instantiating a main class.
To invoke it - you need to create an object of Preethi explicitly.
UPD. as anio suggests - you need to subclass Preethi and instantiate it.
Although abstract classes cannot be used to instantiate objects, they can be used to create object references, because Java's approach to run-time polymorphism is implemented through the use of superclass references. Thus, it must be possible to create a reference to an abstract class so that it can be used to POINT TO A SUBCLASS object.
You can make it not abstract, or create a subclass that invokes super() on your abstract class.
See the code below:
public abstract class Preethi {
// constructor:
Preethi() {
System.out.println("hirerew");
}
public static void main(String[] args) {
// call the constructor:
new Preethi() {}; // "{}" needed because our class is abstract.
}
}
The point here is that you don't always have to create a new class, but can define a 'one-time' class next to the constructor. For example:
public abstract class A {
public abstract void foo();
public A() { foo(); }
}
You could do the following:
A a = new A() {
public void foo() {
System.out.println("hello");
}
};
The output would simply be "hello". A similar method could also be utilized for interfaces.
You are not creating object of Preethi. In order to make call to constructor, You have to remove abstract keyword from class and create it's object
Or create anonymous inner class and it's object as :
new Preethi() {
// abstract method impl
};
Or create sub class of Preethi, and create object of it.
FYI: You can create object references of any abstract class or interfaces. You can not create object of them.
And I think making main class abstract really does not make any sense. Atlease to me.(Tell me if I am wrong)