using System;
class A
{
public virtual void F() {
Console.WriteLine("A.F");
}
public virtual void G() {
Console.WriteLine("A.G");
}
}
class B: A
{
sealed override public void F() {
Console.WriteLine("B.F");
}
override public void G() {
Console.WriteLine("B.G");
}
}
class C: B
{
override public void G() {
Console.WriteLine("C.G");
}
}
In the above question I want to know that the Class c has no method with name f() I mean if I create an object of it and access the method f() will it throw error or not? If yes then I want to know that because of inheritance class c should have a method with name f() of class A ... so I cant call this?
You cannot remove methods in a base class from a derived class; that would violate the LSP, and could be trivially defeated by simply casting to the base. The sealed keyword prevents any derived class from overriding the method; it doesn't hide it.
Related
is it possible to call generic types function.
if not is there a different approach to something like this.
someFunction<T>(){
T.anotherFunction();
}
EDIT
MyModel model = NetworkClient.sendRequest<MyModel>(url);
static Future<T> sendRequest<T>(String URL){
//send request
var res = data.toString();
return T.fromJson(json.decode(res))
}
void main() {
someFunction(Foo());
someFunction(Bar());
}
someFunction<T>(T t) {
if (t is Foo)
t.fooFunc();
else if (t is Bar)
t.barFunc();
else
throw Exception("Unknown type: ${t.runtimeType}");
}
class Foo {
void fooFunc() {
print("foo");
}
}
class Bar {
void barFunc() {
print("bar");
}
}
Put your method (lets say MyMethod) in an interface or base class. Lets say MyInterface.
Then use a constraint on your generic type:
someFunction<T extends MyInterface>(T t){
t.MyMethod();
}
Since you cannot have constructors in an interface, your plan with the fromJson might not work out. I don't know your class structure. But you can write generics with specific constraints in mind.
I have a an instance of A and b an instance of B
a must be able to call a method on b and b must then immediatly call a method on a if some checks pass.
To achieve this I would have cyclic DI
public A(B b) { _b = b; }
public void CallToB() { _b.Method(); }
public void Method() { DoSomething(); }
public B(A a) { _a = a; }
public void Method() { if (SomeCheck()) _a.Method(); }
I know I could get arround this, using events and let b be unaware/independant of a. But it would feel wrong.
Note: I haven't seen an answer to this question where bidirectional communication was made possible.
You can solve this issue by depending on interfaces instead of concrete types and then use property injection. Here is an example:
public interface IA
{
void Method();
}
public class A : IA
{
private readonly IB _b;
public A(IB b){_b = b;}
//...
}
public interface IB
{
void Method();
}
public class B : IB
{
private readonly IA _a;
public B(IA a){_a = a;}
//...
}
public class BCycleDependencyBreaker : IB
{
private IB _b;
public IB b
{
set { _b = value; }
}
public void Method()
{
_b.Method();
}
}
You then use BCycleDependencyBreaker when you compose like this:
var b_cycle_dependency_breaker = new BCycleDependencyBreaker();
//Make a depend on this implementation of b that currently does nothing
A a = new A(b_cycle_dependency_breaker);
//Make b depend on a
B b = new B(a);
//Now, let the proxy implementation delegate calls to the real b
b_cycle_dependency_breaker.b = b;
So basically, I have a situation where I want to inject primitive types into a class (i.e. a String and an Integer). You can think of a URL and port number for an application as example inputs. I have three components:
Now say I have a class, which does take in these params:
public class PrimitiveParamsDIExample {
private String a;
private Integer b;
public PrimitiveParamsDIExample(String a, Integer b) {
this.a = a;
this.b = b;
}
}
So my question here is simple. How do I inject a and b into class PrimitiveParamsDIExample?
In general, this is also asking how to inject parameters that are decided on runtime as well. If I have a and b above, read from STDIN or from an input file, they're obviously going to be different from run to run.
All the more, how do I do the above within the HK2 framework?
EDIT[02/23/15]: #jwells131313, I tried your idea, but I'm getting the following error (this one for the String param; similar one for int):
org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at Injectee(requiredType=String,parent=PrimitiveParamsDIExample,qualifiers
I set up classes exactly as you did in your answer. I also overrode the toString() method to print both variables a and b in PrimitiveParamsDIExample. Then, I added the following in my Hk2Module class:
public class Hk2Module extends AbstractBinder {
private Properties properties;
public Hk2Module(Properties properties){
this.properties = properties;
}
#Override
protected void configure() {
bindFactory(StringAFactory.class).to(String.class).in(RequestScoped.class);
bindFactory(IntegerBFactory.class).to(Integer.class).in(RequestScoped.class);
bind(PrimitiveParamsDIExample.class).to(PrimitiveParamsDIExample.class).in(Singleton.class);
}
}
So now, I created a test class as follows:
#RunWith(JUnit4.class)
public class TestPrimitiveParamsDIExample extends Hk2Setup {
private PrimitiveParamsDIExample example;
#Before
public void setup() throws IOException {
super.setupHk2();
//example = new PrimitiveParamsDIExample();
example = serviceLocator.getService(PrimitiveParamsDIExample.class);
}
#Test
public void testPrimitiveParamsDI() {
System.out.println(example.toString());
}
}
where, Hk2Setup is as follows:
public class Hk2Setup extends TestCase{
// the name of the resource containing the default configuration properties
private static final String DEFAULT_PROPERTIES = "defaults.properties";
protected Properties config = null;
protected ServiceLocator serviceLocator;
public void setupHk2() throws IOException{
config = new Properties();
Reader defaults = Resources.asCharSource(Resources.getResource(DEFAULT_PROPERTIES), Charsets.UTF_8).openBufferedStream();
load(config, defaults);
ApplicationHandler handler = new ApplicationHandler(new MyMainApplication(config));
final ServiceLocator locator = handler.getServiceLocator();
serviceLocator = locator;
}
private static void load(Properties p, Reader r) throws IOException {
try {
p.load(r);
} finally {
Closeables.close(r, false);
}
}
}
So somewhere, the wiring is messed up for me to get an UnsatisfiedDependencyException. What have I not correctly wired up?
Thanks!
There are two ways to do this, but one isn't documented yet (though it is available... I guess I need to work on documentation again...)
I'll go through the first way here.
Basically, you can use the HK2 Factory.
Generally when you start producing Strings and ints and long and scalars like this you qualify them, so lets start with two qualifiers:
#Retention(RUNTIME)
#Target( { TYPE, METHOD, FIELD, PARAMETER })
#javax.inject.Qualifier
public #interface A {}
and
#Retention(RUNTIME)
#Target( { TYPE, METHOD, FIELD, PARAMETER })
#javax.inject.Qualifier
public #interface B {}
then write your factories:
#Singleton // or whatever scope you want
public class StringAFactory implements Factory<String> {
#PerLookup // or whatever scope, maybe this checks the timestamp?
#A // Your qualifier
public String provide() {
// Write your code to get your value...
return whatever;
}
public void dispose(String instance) {
// Probably do nothing...
}
}
and for the Integer:
#Singleton // or whatever scope you want
public class IntegerBFactory implements Factory<Integer> {
#PerLookup // or whatever scope, maybe this checks the timestamp?
#B // Your qualifier
public Integer provide() {
// Write your code to get your value...
return whatever;
}
public void dispose(String instance) {
// Probably do nothing...
}
}
Now lets re-do your original class to accept these values:
public class PrimitiveParamsDIExample {
private String a;
private int b;
#Inject
public PrimitiveParamsDIExample(#A String a, #B int b) {
this.a = a;
this.b = b;
}
}
Note I changed Integer to int, well... just because I can. You can also just use field injection or method injection in the same way. Here is field injection, method injection is an exercise for the reader:
public class PrimitiveParamsDIExample {
#Inject #A
private String a;
#Inject #B
private int b;
public PrimitiveParamsDIExample() {
}
}
There are several ways to bind factories.
In a binder: bindFactory
Using automatic class analysis: addClasses
An EDSL outside a binder: buildFactory
Is there way to overriding method in Dart like JAVA, for example:
public class A {
public void handleLoad() {
}
}
And when overriding:
A a = new A() {
#Override
public void handleLoad() {
// do some code
}
};
No, Dart does not have anonymous classes. You have to create a class that extends A and instantiate it.
No but it much less useful in Dart because you can just reassign function:
typedef void PrintMsg(msg);
class Printer {
PrintMsg foo = (m) => print(m);
}
main() {
Printer p = new Printer()
..foo('Hello') // Hello
..foo = ((String msg) => print(msg.toUpperCase()))
..foo('Hello'); //HELLO
}
However you will need some extra boilerplate to access instance.
Use type Function:
class A {
final Function h
A(this.h);
void handleLoad(String loadResult) { h(loadResult); }
}
Or
class A {
final Function handleLoad;
A(this.handleLoad);
}
A a = new A((String loadResult){
//do smth.
});
I cannot declare class in this manner. May be I am wrong. Is this possible in other way?
class GroupByIterator<TSource, Grouping<TKey, TElement>> {
}
class Grouping<TKey, TElement> {
}
I got a dozen compiler errors on this declaration.
Please, help me define similar declaration.
P.S.
I know the following way, but I want to know that it can be made easier?..
void main() {
var it1 = new GroupByIterator<List, Grouping<int, String>, int, String>();
}
class GroupByIterator<TSource, TResult extends Grouping<TKey, TElement>, TKey, TElement> {
GroupByIterator() {
print('GroupByIterator');
}
}
class Grouping<TKey, TElement> {
}
I want simialr to this.
var it1 = new GroupByIterator<List, Grouping<int, String>>();
class GroupByIterator<TSource, TResult, TKey, TElement, T extends Grouping<TKey, TElement>> implements Iterator<TResult> {
GroupByIterator() {
print('GroupByIterator');
}
}
It seems that you must list all Type parameters in the 'top' level to use it in the following 'lower' levels.