Please explain the following behaviour.
class Base
{
public int num = 3;
public int getNum()
{
return num;
}
public void setNum(int num)
{
this.num = num;
}
}
class child
extends Base
{
public int num = 4;
public child()
{
}
public child(int i)
{
this.num = i;
}
public int getNum()
{
return num;
}
public void setNum(int num)
{
this.num = num;
}
}
public class Main
{
public static void main(String[] args)
{
Base obj2 = new child();
System.out.println(obj2.num);
System.out.println(obj2.getNum());
Base obj3 = new child(10);
System.out.println(obj3.num);
System.out.println(obj3.getNum());
}
}
Output :
3
4
3
10
Here how obj2.num and obj3.num still point to the value 3 which is assigned in the Base class instance variable. Wont it get overidded like the obj2.getNum() and obj3.getNum().
Thanks in advance.
Because the objects are declared with super class type, you get the super member variable value.
If the object was declared with sub class type, the value would be overridden value.
If the Base obj3 = new child(10); is modified to child obj3 = new child(10); the output would be 3 4 10 10
This is well explained here
Related
HandDrawn class extends the super-class Car, as you can see. The problem is it doesn't print out the the String name when i try to print the ArrayList that stores the objects. Btw, the ArrayList stores objects of the class Car.
Calm down, if i did something that offends your little feelings with this question, dont down vote... tell me what's up so i know in the future.
public class HandDrawn extends Card {
private boolean niceDrawing;
public HandDrawn(String name, boolean niceDrawing) {
super(name);
this.niceDrawing = niceDrawing;
}
#Override
public String toString() {
return "HandDrawn{" +
"niceDrawing=" + niceDrawing +
'}';
}
public void setNiceDrawing() {
this.niceDrawing = niceDrawing;
}
public boolean getNiceDrawing(boolean niceDrawing) {
return this.niceDrawing;
}
}
public class Main {
static ArrayList<Card> cards = new ArrayList<>();
public static void main(String[] args) {
cards.add(new HandDrawn("Anna", true));
cards.add(new HandDrawn("Kalle", false));
Main myApp = new Main();
myApp.cardList(cards);
}
public void cardList(ArrayList<Card> e) {
for (int i = 0; i <e.size(); i++) {
System.out.println(e.get(i));
}
}
}
This is the Main class and the HandDrawn class
Again, I don't know what is in your super class "Card" but maybe this will help:
In your HandDrawn.java file:
public class HandDrawn extends Card {
private boolean niceDrawing;
public HandDrawn(String name, boolean niceDrawing) {
super(name);
this.niceDrawing = niceDrawing;
}
#Override
public String toString() {
return "HandDrawn{" + "niceDrawing=" + this.niceDrawing + "}";
}
// Notice I have modified the parameters of your getters
// and setters because it looked as if you had swapped them:
public void setNiceDrawing(boolean niceDrawing) {
this.niceDrawing = niceDrawing;
}
public boolean getNiceDrawing() {
return this.niceDrawing;
}
}
In your Main.java file:
public class Main {
static ArrayList<Card> cards = new ArrayList();
public static void main(String[] args) {
// This is the entry point of your program... execution begins here.
cards.add(new HandDrawn("Anna", true));
cards.add(new HandDrawn("Kalle", false));
cardList(cards);
}
// The following two lines are out of place and should not be in class definition:
// Main myApp = new Main();
// myApp.cardList(cards);
// I added static keyword so that it could be used in call above
public static void cardList(ArrayList<Card> e) {
for (int i = 0; i < e.size(); i++) {
System.out.println(e.get(i));
}
}
If you are wanting to use the "Main" class as a piece in another part of your code then probably that means that execution starts somewhere else and never hits the "main" method. If that is the case you will need to call it explicitly (example: Main.main(null);) or reorganize your code to do it in a constructor for the "Main" class. Then your Main myApp = new Main(); and myApp.cardList(cards); lines would make sense in that context and the cardList method would need to be a non-static member method as you had originally written.
EDIT:
I think I misunderstood your formatting... Your code should work as follows:
In your Main.java file:
public class Main {
static ArrayList<Card> cards = new ArrayList();
public static void main(String[] args) {
// This is the entry point of your program... execution begins here.
cards.add(new HandDrawn("Anna", true));
cards.add(new HandDrawn("Kalle", false));
Main myApp = new Main();
myApp.cardList(cards);
}
public void cardList(ArrayList<Card> e) {
for (int i = 0; i < e.size(); i++) {
System.out.println(e.get(i));
}
}
What were you expecting to see? Again I cannot test your code because I don't have "Card" class but when I use the "HandDrawn" class in place of "Card" (without extending "Card") it works as I would expect and prints:
HandDrawn{niceDrawing=true}
HandDrawn{niceDrawing=false}
So I have a method like so (Method1):
public class Levels extends JFrame{
public void levelClass() {
if(menu.playerClass.equals("Warrior")) {
// I NEED COMMAND HERE
}
}
}
and I want to know how to run this class method (that is in a different class):
public class Classes {
public void listClasses() {
class Warrior { // THIS ONE
int health=100;
int evasionChance=20; // Percentage
int maxAttackDamage=30;
int minAttackDamage=25;
int numHealthPotions=2;
}
}
}
from the first code aka Method1.
Edit
DON'T
Change all:
public class Classes {
public void listClasses() {
class Warrior {
int health=100;
int evasionChance=20; // Percentage
int maxAttackDamage=30;
int minAttackDamage=25;
int numHealthPotions=2;
}
}
}
To:
public class Classes {
public void Warrior {
int health=100;
int evasionChance=20; // Percentage
int maxAttackDamage=30;
int minAttackDamage=25;
int numHealthPotions=2;
}
}
To call a method on a class, you need to instantiate the class.
public class Levels extends JFrame{
public void levelClass() {
if(menu.playerClass.equals("Warrior")) {
// instantiate the Classes class
Classes classes = new Classes();
// call the warrior method
classes.warrior();
}
}
}
I tried to reconstruct the problem in LinqPad:
/*
“Named and Keyed Services”
http://autofac.readthedocs.org/en/latest/advanced/keyed-services.html
*/
const string A = "a";
const string B = "b";
const string MyApp = "MyApp";
void Main()
{
var builder = new ContainerBuilder();
builder
.RegisterType<MyClassA>()
.As<IMyInterface>()
.InstancePerLifetimeScope()
.Keyed<IMyInterface>(A);
builder
.RegisterType<MyClassB>()
.As<IMyInterface>()
.InstancePerLifetimeScope()
.Keyed<IMyInterface>(B);
builder
.RegisterType<MyAppDomain>()
.Named<MyAppDomain>(MyApp);
var container = builder.Build();
var instance = container.ResolveKeyed<IMyInterface>(A);
instance.AddTheNumbers().Dump();
var myApp = container.ResolveNamed<MyAppDomain>(MyApp);
myApp.Dump();
}
interface IMyInterface
{
int AddTheNumbers();
}
class MyClassA : IMyInterface
{
public int AddTheNumbers() { return 1 + 2; }
}
class MyClassB : IMyInterface
{
public int AddTheNumbers() { return 3 + 4; }
}
class MyAppDomain
{
public MyAppDomain([WithKey(A)]IMyInterface aInstance, [WithKey(B)]IMyInterface bInstance)
{
this.ANumber = aInstance.AddTheNumbers();
this.BNumber = bInstance.AddTheNumbers();
}
public int ANumber { get; private set; }
public int BNumber { get; private set; }
public override string ToString()
{
var sb = new StringBuilder();
sb.AppendFormat("ANumber: {0}", this.ANumber);
sb.AppendFormat(", BNumber: {0}", this.BNumber);
return sb.ToString();
}
}
when MyApp is “dumped” I am seeing ANumber: 7, BNumber: 7 which tells me that WithKey(A) is not returning the expected instance. What am I doing wrong here?
Looks like you forgot to register the consumers using WithAttributeFilter which is what allows this to work. Like:
builder.RegisterType<ArtDisplay>().As<IDisplay>().WithAttributeFilter();
In C#, why when we can define a class method and access to a method by class name directly, we should/some people define an object instead and then create an instance of that object?
Class1:
class Class1
{
public static int PrintX(int x)
{
return x;
}
private int y;
public int PrintY(int z)
{
return this.y = z;
}
}
Main Method:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Class1.PrintX(9));
Class1 newClass = new Class1();
Console.WriteLine(newClass.PrintY(9));
}
}
Both ways print out 9. Why should I use an object method and then create an instance of it?!
If you have to ask the question, then you shouldn't (use an object method). However, if you create two classes, they will affect each other.
Class1 newClassA = new Class1();
Class1 newClassB = new Class1();
Console.WriteLine(newClassA.PrintY(1));
Console.WriteLine(newClassB.PrintY(9));
After this code, newClassA's y is 9.
From the Autofac documentation I can see how to get all registrations for a class T:
public T[] ResolveAll<T>()
{
return _container.Resolve<IEnumerable<T>>().ToArray();
}
But when I only have the Type available, how can I get the equivalent results?
public Array ResolveAll(Type service)
{
return _container.Resolve( ???
}
I am trying to implement a wrapper class which has a pre-defined interface.
EDIT
For quick reference, the answer from Matthew Watson (with relevant ideas from David L) is:
public Array ResolveAll(Type service)
{
var typeToResolve = typeof(IEnumerable<>).MakeGenericType(service);
return _container.Resolve(typeToResolve) as Array;
}
Here is an example. I've added asserts to prove that the types returned from ResolveAll<T>(this IContainer self) are the same (and in the same order) as those returned from ResolveAll(this IContainer self, Type type):
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Autofac;
using Autofac.Core;
namespace AutofacTrial
{
public abstract class Base
{
public abstract string Name { get; }
public override string ToString()
{
return Name;
}
}
public sealed class Derived1: Base
{
public override string Name
{
get
{
return "Derived1";
}
}
}
public sealed class Derived2: Base
{
public override string Name
{
get
{
return "Derived2";
}
}
}
public sealed class Derived3: Base
{
public override string Name
{
get
{
return "Derived3";
}
}
}
static class Program
{
static void Main()
{
var builder = new ContainerBuilder();
builder.RegisterType<Derived1>().As<Base>();
builder.RegisterType<Derived2>().As<Base>();
builder.RegisterType<Derived3>().As<Base>();
var container = builder.Build();
var array1 = container.ResolveAll(typeof(Base));
var array2 = container.ResolveAll<Base>();
Trace.Assert(array1.Length == 3);
Trace.Assert(array2.Length == 3);
for (int i = 0; i < array1.Length; ++i)
{
Trace.Assert(array1[i].GetType() == array2[i].GetType());
Console.WriteLine(array1[i]);
}
}
public static T[] ResolveAll<T>(this IContainer self)
{
return self.Resolve<IEnumerable<T>>().ToArray();
}
public static object[] ResolveAll(this IContainer self, Type type)
{
Type enumerableOfType = typeof(IEnumerable<>).MakeGenericType(type);
return (object[]) self.ResolveService(new TypedService(enumerableOfType));
}
}
}
The underling implementation is the same
I also used Reflector to look at the implementation of Resolve<IEnumerable<T>>(), and it winds up doing this:
public static TService Resolve<TService>(this IComponentContext context, IEnumerable<Parameter> parameters)
{
return (TService) context.Resolve(typeof(TService), parameters);
}
which calls:
public static object Resolve(this IComponentContext context, Type serviceType, IEnumerable<Parameter> parameters)
{
return context.ResolveService(new TypedService(serviceType), parameters);
}
So the two must be equivalent, since they are implemented that way.
You can invoke _container.Resolve by calling your wrapped method via reflection (MSDN), but in doing so you will lose your compile-time type safety.
public class Container
{
public T[] ResolveAll<T>()
{
return _container.Resolve<IEnumerable<T>>().ToArray();
}
public object ResolveAllGeneric(Type t)
{
MethodInfo method = GetType().GetMethod("ResolveAll")
.MakeGenericMethod(new Type[] { t });
return method.Invoke(this, new object[] { });
}
}