Please have a look at below given code.
<?php
class Bar
{
public function test() {
$this->testPrivate();
$this->testPublic();
}
public function testPublic() {
echo "Bar::testPublic\n";
}
private function testPrivate() {
echo "Bar::testPrivate\n";
}
}
class Foo extends Bar
{
public function testPublic() {
echo "Foo::testPublic\n";
}
private function testPrivate() {
echo "Foo::testPrivate\n";
}
}
$myFoo = new foo();
$myFoo->test(); // Bar::testPrivate
// Foo::testPublic
?>
In above example, when we called $myFoo->test();it called testPrivate of Bar class
But how come it called testPublic of Foo class.
Can any one help me in this ?
Bar.testPrivate and Foo.testPrivate have to be protected methods instead of private ones. See here for more:
http://php.net/manual/en/language.oop5.visibility.php
Because test() is NOT in Foo and is running in Bar scope. Bar scope can't access to Foo private methods.
Just add test() to Foo...
Indeed one of the comments on the visibility page does reiterate this:
"private methods never participate in the in the overriding because these methods are not visible in the child classes."
It does feel a bit strange because you would think that the child class would override the parent with the method names being the same, but its not the case with private methods and the parents method takes precidence here, so best to use protected methods if you want to override.
Related
I'm able to do something like the following in TypeScript
class Foo {
private constructor () {}
}
so this constructor is accessible only from inside the class itself.
How to achieve the same functionality in Dart?
Just create a named constructor that starts with _
class Foo {
Foo._() {}
}
then the constructor Foo._() will be accessible only from its class (and library).
A method without any code must be something like this
class Foo {
Foo._();
}
Yes, It is possible, wanna add more information around it.
A constructor can be made private by using (_) underscore operator which means private in dart.
So a class can be declared as
class Foo {
Foo._() {}
}
so now, The class Foo doesn't have a default constructor
Foo foo = Foo(); // It will give compile time error
The same theory applied while extending class also, It's also impossible to call the private constructor if it declares in a separate file.
class FooBar extends Foo {
FooBar() : super._(); // This will give compile time error.
}
But both above functionality works if we use them in the same class or file respectively.
Foo foo = Foo._(); // It will work as calling from the same class
and
class FooBar extends Foo {
FooBar() : super._(); // This will work as both Foo and FooBar are declared in same file.
}
you can create following class in order to get a singleton instance
class Sample{
factory Sample() => _this ??= Sample._();
Sample._(); // you can add your custom code here
static Sample _this;
}
Now in the main function you can call the sample constructor
void main(){
/// this will return the _this instace from sample class
Sample sample = Sample();
}
just use abstract class.
Because you can't instantiate abstract class
I'm trying to bind a class C from a third-party's package.
It injects a class Foo instance via constructor -
class C {
public C(#Inject Foo foo) {
...
}
...
}
In my application, I've two instances of Foo bound -
bind(Foo.class)
.to(FooImpl1.class);
bind(Foo.class)
.annotatedWith(Names.named("SpecialFoo"))
.to(FooImpl2.class);
when C is bound, I want the Named Foo instance to be used. However I do not have access to the code in which C is defined, to be able to put any annotations.
Is there a suggested way of doing that, short of writing my own provider method for C?
You could look into using PrivateModule. In your example, it will be something like:
public class CModule extends PrivateModule {
protected void configure() {
bind(Foo.class).to(FooImpl2.class);
bind(C.class);
expose(C.class);
}
}
Let us suppose the following situation. There is a global module AppModule, a scoped module ScopedModule, a class Main and a class Foo in an application's main variant. Moreover, there is a debug variant with a module DebugAppModule, a module DebugScopedModule and a class Bar. Only the debug variant may know about Bar.
The main variant contains the following relevant code excerpts.
#Module AppModule { /*..*/ }
#Module(injects=Main.class, addsTo=AppModule.class)
ScopedModule { #Provides Foo provideFoo() { return new Foo(); } }
class Main { scopedGraph = graph.plus(new ScopedModule(this)); }
class Foo { /*..*/ }
// In the entry point of the application
ObjectGraph.create(new AppModule());
The debug variant contains the following relevant code excerpts.
#Module(addsTo=AppModule.class, overrides=true) DebugAppModule { /*..*/ }
#Module(injects=Main.class, addsTo=DebugAppModule.class, overrides=true)
DebugScopedModule { #Provides Foo provideFoo() { return new Bar(); } }
class Bar extends Foo { /*..*/ }
// In the entry point of the application
ObjectGraph.create(new AppModule(), new DebugAppModule());
My research and experimentation revealed that it is not possible to override #Provides-methods in scoped modules, i.e. when plusing a module. See for example How to Mock Dagger Activity Object Graphs. That is, in the debug variant whenever a Foo is injected it still would be a Foo and not a Bar. This makes sense because the class Main has a fixed dependency to ScopedModule (note the new).
It seems to me that there should be a way to inject scoped modules themselves – meta-injection so to say :). That is, AppModule could provide ScopedModule for Main. The problem is that ScopedModule's constructor needs an instance of Main and so AppModule would need to retain an instance of Main and that would not fly (e.g. in an Android-specific context where Main would be an Activity).
So what is the best alternative way to achieve the effect of overriding #Provides-methods when using scoped modules?
With the latest version of Dagger, overriding #Provided methods are not permitted.
I found a good solution here. Thanks to #vaughandroid
Basically,
When you are providing your module into your component, you can override your methods.
MyComponent component = DaggerMyComponent.builder()
.appModule(new AppModule() {
#Override public Foo provideFoo() {
return new Bar();
}
})
.build();
This has worked for me and I guess it'll work for you.
I need to make changes to other domain classes when an instance of a particular domain class is deleted. What is the best way to do this? I don't want to wait until commit or flush so I don't think the "beforeDelete" callback will help. I would like to "override" delete, do some stuff and call super.delete():
class Foo {
Bar bar
void delete() {
if (bar) bar.foo = null
super.delete() -- this doesn't work
}
}
Currently I have named "delete" cancel but would like to call it "delete" but then I cannot call the original delete().
To add to what #sbglasius said, here's the link to the docs on GORM events
Complete example:
class Foo {
Bar bar
def beforeDelete() {
if(bar) {
bar.foo = null
}
}
}
I haven't tried overriding GORM methods myself, but this might give some insight on what's involved:
"Overloading" standard GORM CRUD methods
I would put the "delete" logic in a service and call that instead:
class FooService {
def deleteInstance(foo) {
if (foo?.bar) {
foo.bar.foo = null
// might have to call foo.bar.save() here
// then foo.bar = null
}
foo.delete()
}
}
I've got a grails app with Service classes that inherit from Groovy's GroovyInterceptable:
class customerSerrvice implements GroovyInterceptable {
private List<Customer> customers
def invokeMethod(String name, args) {
log.debug "=======>INVOKING method [$name] with args:$args"
}
void foo() {
customers.each { doSomething(it) }
}
void doSomething(Customer cust) { log.debug "doSomething invoked with $cust" }
}
The above is a greatly simplified representation, but it gives you the idea. If I call foo() or doSomething() directly from another class, the invokeMethod gets called like it is supposed to. However, when foo() calls doSomething(), that call is not intercepted in invokeMethod.
If I change from
customers.each { doSomething(it) }
to
for(Customer cust: customers) { doSomething(cust) }
then the invokeMethod gets called just fine.
So is there something about closures and GroovyInterceptable that don't go together? Is there any way to get the invokeMethod to work with closures short of changing them all out?
Thanks
Confirmed as a bug, old link:
http://jira.codehaus.org/browse/GROOVY-4610, new link:
https://issues.apache.org/jira/browse/GROOVY-4610