Showing posts with label Class. Show all posts
Showing posts with label Class. Show all posts

Sunday, March 08, 2009

Using get_class() in superclass

<?php
abstract class bar {
public function __construct()
{
var_dump(get_class($this));
var_dump(get_class());
}
}

class foo extends bar {
}

new foo;
?>


The above example will output:

string(3) "foo"
string(3) "bar"

Reference:
http://cn.php.net/manual/en/function.get-class.php

Tuesday, January 06, 2009

Rails module include way

# Rails module include way
# 以下方式的代码在rails中源码中的相当多见,其中的self.included(base)方法是一个回调方法,当此module被其他名为base的module(或者class)include的时候触发此方法。通过class_eval,include,extend加入了实例方法和类方法到base中,代码划分得很干净。

module ActionController
module Components
def self.included(base)
base.class_eval do
include InstanceMethods
extend ClassMethods
helper HelperMethods
end
end

module ClassMethods
end

module HelperMethods
end

module InstanceMethods
end
end
end

Monday, December 22, 2008

php中self关键字说明

self一般指向当前类的静态方法和常量,用self::加方法名和常量名方式引用。
$this则是指向当前类的实例对象,用$this->加方法名和实例变量方式引用。
在一些参数为callback的方法里,可以用字符串'self'形式指向当前类,而不要直接用self,如call_user_func('self', $method)中。
另外self引用的总是当前类的方法和常量,子类调用父类的静态方法,其中的父类方法中的self仍是指向父类本身的,如果子类的同名方法覆盖了父类方法,则可以用parent::来引用父类方法。

<?php
interface AppConstants {
const FOOBAR = 'Hello, World.';
}

class Example implements AppConstants {
public function test() {
echo self :: FOOBAR;
}
}

$obj = new Example();
$obj->test(); // outputs "Hello, world."

class MyClass {
const NAME = 'Foo';

protected function myFunc() {
echo "MyClass::myFunc()\n";
}
static public function display() {
echo self :: NAME;
}
static public function getInstance() {
$instance = new self;
return $instance;
}
}

class ChildClass extends MyClass {
const NAME = 'Child';

// Override parent's definition
public function myFunc() {
// But still call the parent function
parent :: myFunc();
echo "ChildClass::myFunc()\n";
}
}

$class = new ChildClass();
$class->myFunc();


echo('Class constant: ');
ChildClass :: display();
echo('Object class: ');
echo(get_class(ChildClass :: getInstance()));
?>

== output ==
Hello, World.
MyClass::myFunc()
ChildClass::myFunc()
Class constant: Foo
Object class: MyClass
另外可以再参考一个php 5.3.0的运行时绑定(迟绑定)的用法,地址是:
http://cn2.php.net/oop5.late-static-bindings

Tuesday, November 04, 2008

静态成员类与非静态成员类的区别

/**
* 静态成员类与非静态成员类的区别
*/
public class StaticMemberType {

// Interfaces, enumerated types, 和annotation types 无论是否声明static,它们都是static的。
static class StaticInnerClass {
public void test() {
System.out.println("Static Nested Class Method.");

}
}

public void test() {
new NonStaticInnerClass().test();
}

public class NonStaticInnerClass {
// 非静态成员类不可以包含任何static字段、methods或者类型,除非同时使用了static和final的常量字段之外。
// static String CONST1 = "TEST"; // error
final static String CONST2 = "TEST";
public void test() {
System.out.println("Non Static Inner Class.");
}
}

public static void main(String[] args) {
new StaticMemberType.StaticInnerClass().test();

StaticMemberType staticMemberType = new StaticMemberType();
staticMemberType.test();
// new StaticMemberType.NonStaticInnerClass().test(); // error
}
}

Saturday, March 22, 2008

Simple JavaScript Inheritance

John Resig published a great article on his blog, which brought out a smiple javascript inheritance resolution:

// Inspired by base2 and Prototype
(function(){
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;

// The base Class implementation (does nothing)
this.Class = function(){};

// Create a new Class that inherits from this class
Class.extend = function(prop) {
// "super" is a FutureReservedWord in ECMAScript v3.
var _super = this.prototype;

// Instantiate a base class (but only create the instance,
// don't run the init constructor)
// SubClass may define init() function, "new this()" should prevent init() function to be excuted.
initializing = true;
var prototype = new this();
initializing = false;

// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" && fnTest.test(prop[name]) ?
(function(name, fn){
// return a cloures, which return results of function prop[name](arguments)
return function() {
//save a reference to the old this._super (disregarding if it actually exists)
//and restore it after we're done.
var tmp = this._super;

// Add a new ._super() method that is the same method
// but on the super-class
// fn function body has statement such as "this._super()"
// this._super will be invoked by function fn
this._super = _super[name];

// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;

return ret;
};
})(name, prop[name]) :
prop[name];
}

// The dummy SubClass constructor
function SubClass() {
// All construction is actually done in the init method
if ( !initializing && this.init )
this.init.apply(this, arguments);
}

// Populate our constructed prototype object
SubClass.prototype = prototype;

// Enforce the constructor to be what we expect
// else SubClass.constructor is Function
SubClass.constructor = SubClass;

// And make this SubClass extendable
SubClass.extend = arguments.callee;

return SubClass;
};
})();

Example:

var A = Class.extend({
value:"A",
doStuff:function(){
return this.value;
}
});
var B = A.extend({});
var C = B.extend({
doStuff:function(){
return this._super();
}
});
var c = new C;
alert(c.doStuff());

function doc(argument) {
document.write(argument);
}

var Person = Class.extend({
init: function(isDancing){
this.dancing = isDancing;
},
dance: function(){
return this.dancing;
}
});
doc(Person.constructor);

var Ninja = Person.extend({
init: function(){
this._super( false );
},
dance: function(){
// Call the inherited version of dance()
return this._super();
},
swingSword: function(){
return true;
}
});
doc(Ninja.constructor);

var p = new Person(true);
doc(p.dance()); // => true

var n = new Ninja();
doc(n.dance()); // => false
doc(n.swingSword()); // => true

// Should all be true
doc(p instanceof Person && p instanceof Class && n instanceof Ninja && n instanceof Person && n instanceof Class);

Wednesday, February 13, 2008

Ruby class variable, class attribute(class instance variable), class constant tips


class Class_Attribute
@var = 1 #class attribute or class instance variable

def initialize
@var = 2 #instance attribute
end

def report
@var # instance attribute, not the class attribute
end

def Class_Attribute.report
@var # class attribute
end
end

class Child_A < Class_Attribute
@var = 3
end

puts Class_Attribute.report #=> 1
puts Class_Attribute.new.report #=> 2
puts Child_A.report #=> 3
puts Child_A.new.report #=> 2

class Class_Constant
VAR = [ 'a' ]
VAR2 = [ 'b' ]

def self.report
VAR2[0]
end
end

class Child_C < Class_Constant
VAR2 = [ 'c' ]
end

puts Class_Constant::VAR[0] #=> 'a'
puts Class_Constant::VAR2[0] #=> 'b'
puts Class_Constant.report #=> 'b'
puts Child_C::VAR2[0] #=> 'c'
puts Child_C.report #=> 'b'
puts Child_C::VAR[0] #=> 'a'

from David A. Black:

@@avar = 1
class A
@@avar = "hello"
end
puts @@avar # => hello

A.class_eval { puts @@avar } # => hello

If you’re just looking to store some data in a variable which is unique to your class, but accessible from instances or externally, why not just use instance variables?

class A
@foo = "bar"
class << self; attr_reader :foo; end
end
nil
A.foo #=> "bar"

references:http://www.oreillynet.com/ruby/blog/2007/01/nubygems_dont_use_class_variab_1.html

Monday, January 07, 2008

NOTE CLASS OR MODULE? [R4R page 175]

When you see a construct like :
ActionController::Routing::Route
you can’t tell from that construct what’s a class and what’s a module. If there’s a call to new, you can be pretty sure the last element in the chain is a class, but otherwise the last element could be any constant—class, module, or other—and the elements on the left could be either classes or modules. In many cases, the fact that you can’t tell classes from modules in this kind of context doesn’t matter; what matters is the nesting or chaining of names in a way that makes sense. That’s just as well, because
you can’t tell what’s what without looking at the source code or the documentation. This is a consequence of the fact that classes are modules—the class Class is a subclass of the class Module—and in many respects (with the most notable exception being the fact that classes can be instantiated), their behavior is similar.

Wednesday, January 02, 2008

Ruby get reference to a singleton class of object


class Object
class << self
def self_class
self
end
end

def singleton_class
class << self
self
end
end
end
a = [1,2,3]
p a
puts Array.self_class
puts a.singleton_class

E:\>ruby singleton_class.rb
[1, 2, 3]
Array
#<Class:#<Array:0x294053c>>

Friday, November 16, 2007

R4R and PR2 environment top-level method 学习笔记

R4R
Defining a top-level method
Suppose you define a method at the top level:


def talk
puts "Hello"
end

Who, or what, does the method belong to? It’s not inside a class or module definition block, so it doesn’t appear to be an instance method of a class or module. It’s not attached to any particular object (as in def obj.talk), so it’s not a singleton method. What is it?
By special decree (this is just the way it works!), top-level methods are private instance methods of the Kernel module.
That decree tells you a lot.
Because top-level methods are private, you can’t call them with an explicit receiver; you can only call them by using the implied receiver, self. That means self must be an object on whose method search path the given top-level method lies.

The default object (self) and scope
But every object’s search path includes the Kernel module, because the class Object mixes in Kernel, and every object’s class has Object as an ancestor. That means you can always call any top-level method, wherever you are in your program.
It also means you can never use an explicit receiver on a top-level method.
To illustrate this, let’s extend the talk example. Here it is again, with some code that exercises it:

def talk
puts "Hello"
end
puts "Trying 'talk' with no receiver..."
talk
puts "Trying 'talk' with an explicit receiver..."
obj = Object.new
obj.talk

The first call to talk succeeds; the second fails, because you’re trying to call a private method with an explicit receiver.
The rules concerning definition and use of top-level methods brings us all the way back to some of the bareword methods we’ve been using since as early as chapter1(R4R book). You’re now in a position to understand exactly how those methods work.

Programming Ruby 2nd
Top-Level Execution Environment
Many times in this book we’ve claimed that everything in Ruby is an object. However, we’ve used one thing time and time again that appears to contradict this—the top-level Ruby execution environment.
puts "Hello, World"
Not an object in sight. We may as well be writing some variant of Fortran or BASIC.
But dig deeper, and you’ll come across objects and classes lurking in even the simplest code.
We know that the literal "Hello, World" generates a Ruby String, so that’s one object. We also know that the bare method call to puts is effectively the same as self.puts. But what is self?
self.class ! Object
At the top level, we’re executing code in the context of some predefined object. When we definemethods, we’re actually creating (private) instancemethods for class Object.
This is fairly subtle; as they are in class Object, these methods are available everywhere.
And because we’re in the context of Object, we can use all of Object’s methods (including those mixed-in from Kernel) in function form. This explains why we
can call Kernel methods such as puts at the top level (and indeed throughout Ruby): these methods are part of every object. Top-level instance variables also belong to this top-level object.

命令行中定义的其实是定义在Kernel中的私有方法,并被Mix-in到Object类中成为其对象私有实例方法。因为class Module (< Object)和class Class (< Module)这3者的继承关系,所以控制台里定义的方法在module和class实例对象中可以调用。

Friday, August 10, 2007

Classical Inheritance in JavaScript

Classical Inheritance in JavaScript


<script type="text/javascript" charset="utf-8">
function doc(argument) {
document.write("<p>\n");
document.write(argument);
document.write("</p>\n");
}
Function.prototype.method = function (name, func) {
this.prototype[name] = func;
return this;
};
Function.method('inherits', function (parent) {
var d = {}, p = (this.prototype = new parent());
this.method('uber', function uber(name) {
if (!(name in d)) {
d[name] = 0;
}
var f, r, t = d[name], v = parent.prototype;
if (t) {
while (t) {
v = v.constructor.prototype;
t -= 1;
}
f = v[name];
} else {
f = p[name];
if (f == this[name]) {
f = v[name];
}
}
d[name] += 1;
r = f.apply(this, Array.prototype.slice.apply(arguments, [1]));
d[name] -= 1;
return r;
});
return this;
});
Function.method('swiss', function (parent) {
for (var i = 1; i < arguments.length; i += 1) {
var name = arguments[i];
this.prototype[name] = parent.prototype[name];
}
return this;
});

function Parenizor(value) {
this.setValue(value);
}

Parenizor.method('setValue', function (value) {
this.value = value;
return this;
});

Parenizor.method('getValue', function () {
return this.value;
});

Parenizor.method('toString', function () {
return '(' + this.getValue() + ')';
});

var myParenizor = new Parenizor(0);
var myString = myParenizor.toString();
doc(myParenizor.value);
doc(myString);

function ZParenizor(value) {
this.setValue(value);
}

ZParenizor.inherits(Parenizor);

ZParenizor.method('toString', function () {
if (this.getValue()) {
return this.uber('toString');
}
return "-0-";
});

/*There is another way to write ZParenizor. Instead of inheriting from Parenizor, we write a constructor that calls the Parenizor constructor, passing off the result as its own. And instead of adding public methods, the constructor adds privileged methods.

function ZParenizor2(value) {
var that = new Parenizor(value);
that.toString = function () {
if (this.getValue()) {
return this.uber('toString');
}
return "-0-"
};
return that;
}*/

var myZParenizor = new ZParenizor(0);
var myString = myZParenizor.toString();
doc(myZParenizor.value);
doc(myString);
</script>

Sunday, August 05, 2007

prototype javascript library Class example


<script type="text/javascript" charset="utf-8">
function doc (argument) {
document.write(argument);
document.write("<br />\n");
}
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}

var MyClass = Class.create();
MyClass.prototype = {
initialize: function (msg) {
this.msg = msg;
return msg;
},

showMsg: function () {
doc(this.msg);
}
}

var c = new MyClass('test'); // Class.create('test')
c.showMsg();

var o = {
name: 'test it',
sex: 'man',
info: function () {
return this.name + " and " + this.sex;
},
ivk: function () {
return this.info.apply(this); // invoke this.info function
}
}

doc(o.info());
doc(o.ivk());

/*function TestThis () {
doc(this); // object Window
this.name = 'name test';
this.sex = 'name man';
}
var t = TestThis();
doc(name);
doc(self.name);
doc(this.sex);
for (var p in this) {
doc(this['p']);
}*/
</script>

The Global object holds the global properties and methods listed. These properties and methods do not need to be referenced or invoked through any other object. Any variables and functions you define in your own top-level code become properties of the Global object. The Global object has no name, but you can refer to it in top-level code (i.e. outside of methods) with the this keyword. In client-side JavaScript, the Window object serves as the Global object. It has quite a few additional properties and methods, and can be referred to as window.

Saturday, July 14, 2007

static variable of Javascript


<script type="text/javascript" charset="utf-8">
function doc (argument) {
document.write(argument);
document.write("<br />\n");
}

// Define a static variable to hold the running static_var over all calls
// Can't claim static variable with key "var", this is function Object's properties
function doSome (a) {
doSome.static_var ++;
return a + doSome.static_var;
}
doc(typeof doSome); //function Object
doSome.static_var = 0; // var doSome.static_var = 0 will error.
doc(doSome(1)); //2
doc(doSome(1)); //3
doc(doSome(1)); //4
doSome.static_var = 0;
doc(doSome(1)); //2
for (i in doSome)
{
doc(i);
/*static_var
prototype
bind
bindAsEventListener*/
}
</script>

Class Properties
In addition to instance properties and properties of prototypes, JavaScript allows you to define class properties (also known as static properties), properties of the type rather than of a particular object instance. An example of a class property is Number.MAX_VALUE. This property is a type-wide constant, and therefore is more logically located in the class (constructor) rather than individual Number objects. But how are class properties implemented?
Because constructors are functions and functions are objects, you can add properties to constructors. Class properties are added this way. Though technically doing so adds an instance property to a type’s constructor, we’ll still call it a class variable. Continuing our example,

doSome.static_var = 0;

defines a class property of the doSome object by adding an instance variable to the constructor. It is important to remember that static properties exist in only one place, as members of constructors. They are therefore accessed through the constructor rather than an instance of the object.
As previously explained, static properties typically hold data or code that does not depend on the contents of any particular instance. The toLowerCase() method of the String object could not be a static method because the string it returns depends on the object on which it was invoked. On the other hand, the PI property of the Math object (Math.PI) and the parse() method of the String object (String.parse()) are perfect candidates, because they do not depend on the value of any particular instance. You can see from the way they are accessed that they are, in fact, static properties. The isMetallic property we just defined is accessed similarly, as doSome.static_var.

Friday, July 06, 2007

difference usage obj.send and mod.module_eval


class A
def fred
puts "In Fred"
end

def create_method(name, &block)
self.class.send(:define_method, name, &block) # obj.send
end

def custom_method(name, &block)
self.class.module_eval {define_method(name, &block)} # mod.module_eval, class_eval alias module_eval
# A.module_eval {define_method(name, &block)}
end

define_method(:wilma) { puts "Charge it!" }

end

class B < A
define_method(:barney, instance_method(:fred)) #
end

b = B.new
p b

b.barney

b.wilma

b.create_method(:betty) { puts 'betty' }
b.betty

b.custom_method(:test) {puts 'test'}
b.test

##
#In Fred
#Charge it!
#betty
#test

CLASS AND MODULE DEFINITIONS[programming ruby 2nd]


# programming ruby 2nd
# CLASS AND MODULE DEFINITIONS 373
class OnceTest

# @__#{id.to_i}__ = [__#{id.to_i}__(*args, &block)]
def OnceTest.once(*ids)
for id in ids
module_eval <<-"end;"
alias_method :__#{id.to_i}__, :#{id.to_s}

private :__#{id.to_i}__

def #{id.to_s}(*args, &block)
if @__#{id.to_i}__
puts 'exist cache'
puts @__#{id.to_i}__.inspect
end
(@__#{id.to_i}__ ||= [__#{id.to_i}__(*args, &block)])[0]
end

end;
end
end

def p1
# complex process
puts 'p1'
return 1
# the body of a particular method should be invoked only once, The value returned by that first call should be cached.
end

def p2
# complex process
puts 'p2'
return 2
# 方法体内语句只会执行一次,方法返回的结果会被缓存。
end

once :p1, :p2
# 这些方法都要在此语句之前定义
# 原来的p1和p2方法在once里被重新定义了一个同名方法
# 原来方法名被改为__#{id.to_i}__,格式如:(__nnn__)
# 在once方法体里将原来方法调用后生成的结果放到@__#{id.to_i}__这个实例变量中
# 第二次调用相同方法体时,直接返回@__#{id.to_i}__
end

o = OnceTest.new
3.times do |i|
o.p1
o.p2
end

#p1
#p2
#exist cache
#[1]
#exist cache
#[2]
#exist cache
#[1]
#exist cache
#[2]

Saturday, March 24, 2007

Class Abstraction

PHP 5 introduces abstract classes and methods. It is not allowed to create an instance of a class that has been defined as abstract. Any class that contains at least one abstract method must also be abstract.Methods defined as abstract simply declare the method's signature they cannot define the implementation.
class中包括一个abstract方法以上, 则此class也为abstratct class。Abstract method只是在abstract class 声明一下,并确定此method的visibility,并不具体实现这些方法的功能。这些是在继承类subclass中实现。

When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or weaker) visibillity. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public.


<?php
abstract class AbstractClass
{
abstract protected function getValue();
abstract public function addPrefix($prefix);

public function putOut()
{
echo "<br>", $this->getValue(), "<br>";
}
}

class ConcreteClass extends AbstractClass
{
public function getValue()
{
echo "<br>", "Concrete Class.", "<br>";
}
// Fatal error: Class ConcreteClass contains 1 abstract method and must therefore be declared abstract or implement the remaining methods (AbstractClass::addPrefix)
// Fatal error: Access level to ConcreteClass::addPrefix() must be public (as in class AbstractClass)
public function addPrefix($prefix)
{
echo "<br>", "{$prefix}Concrete Class.", "<br>";
}
}

$c = new ConcreteClass();
$c->putOut();
$c->addPrefix("yu_");
?>

Friday, March 23, 2007

PHP5 class basic

The Basics

class

Every class definition begins with the keyword class, followed by a class name, which can be any name that isn't a reserved word in PHP. Followed by a pair of curly braces, which contains the definition of the classes members and methods. A pseudo-variable, $this is available when a method is called from within an object context. $this is a reference to the calling object (usually the object to which the method belongs, but can be another object, if the method is called statically from the context of a secondary object). This is illustrated in the following examples:
Example 19-1. $this variable in object-oriented language


<?php
class A
{
function foo()
{
if (isset($this)) {
echo '$this is defined (';
echo get_class($this);
echo ")\n";
} else {
echo "\$this is not defined.\n";
}
}
}

class B
{
function bar()
{
A::foo();
}
}

$a = new A();
$a->foo();
A::foo();
$b = new B();
$b->bar();
B::bar();
?>
The above example will output:

$this is defined (a)
$this is not defined.
$this is defined (b)
$this is not defined.

Example 19-2. Simple Class definition

<?php
class SimpleClass
{
// member declaration
public $var = 'a default value';

// method declaration
public function displayVar() {
echo $this->var;
}
}
?>
The default value must be a constant expression, not (for example) a variable, a class member or a function call.
Example 19-3. Class members' default value

<?php
class SimpleClass
{
// invalid member declarations:
public $var1 = 'hello '.'world';
public $var2 = <<hello world
EOD;
public $var3 = 1+2;
public $var4 = self::myStaticMethod();
public $var5 = $myVar;

// valid member declarations:
public $var6 = myConstant;
public $var7 = self::classConstant;
public $var8 = array(true, false);


}
?>

Saturday, March 17, 2007

Hierarchy of javascript and java










JavaScript

Java


function Manager () {
this.reports = [];
}
Manager.prototype = new Employee;
function WorkerBee () {
this.projects = [];
}
WorkerBee.prototype = new Employee;



public class Manager extends Employee {
public Employee[] reports;
public Manager () {
this.reports = new Employee[0];
}
}
public class WorkerBee extends Employee {
public String[] projects;
public WorkerBee () {
this.projects = new String[0];
}
}