java学习——Java面向对象基础知识

笔记12 发布于 2016/11/05 16:39
阅读 445
收藏 1

在Java编程思想中提到了面向对象程序设计的五个特征:

  • 万物皆为对象。也就是说世界上所有的事物都能通过抽象变成一个可以实现的对象。比如动物、建筑物、服务。

  • 程序是对象的集合,他们通过发送消息来告知彼此所有做的。程序是把要解决的问题抽象为若干的对象,这些对象之间通过消息来通知彼此做什么和传递数据。比如:动物吃食物,这个程序包含了动物、食物两种对象,通过吃这一动作来告知动物吃食物。

  • 每个对象都有自己由其他对象构成的存储。意思是对象之间可以是包含的关系,一个对象中可以含有另外一个对象,这样就构成了一个新的对象。比如:发动机,汽车,汽车这一对象中包含发动机。

  • 每个对象都拥有其类型。每个对象都是某个类的一个实例,这个类就是抽象出来的一类事物,这个类与其他类之间的重要区别就是行为,它能接受什么样的消息。比如:动物和食物,动物有吃的行为,移动的行为,而食物是没有的。

  • 某一特定类型的所有对象都可以接受同样的消息。这是判断某一对象是不是某个类型的标准。比如你定义了动物的一些行为,比如移动,那么所有的动物都要相应移动这一消息,无论你是跑着移动、飞着移动,还是游着移动。


上面是面向对象程序设计的基本特征,下面介绍面向对象中用到的一些关键词。


类:


类描述了具有相同特性(数据元素)和行为(功能)的对象集合,也是一个数据类型。比如说动物,它有重量、大小的特征(数据元素),也有移动、吃的行为(功能)。


对象:


对象是具有状态、行为和标识的,是上面类的一个实例。每一个对象都有内部数据(它描述该对象的状态)和方法(它产生行为),并且每一个对象都可以与其他对象区分开来,就是一个对象在内存中都有一个唯一的地址。在Java中对象都必须通过new来产生。


继承:


把某些具有相同属性和行为的事物抽象起来集中到一个类中,一个新类可以从这个类中派生,新类具有父类的所有的行为和特征,这个过程称为类继承。新类继承了原始类的特性,新类称为原始类的派生类(子类),而原始类称为新类的基类(父类),在Java中是通过 ChildCalss extends FartherClass 这种方式实现的。


抽象:


抽象在编程中就是把你要解决的问题分解为一个一个的小问题,直到你不能再分解为止,然后把你分解的这些小问题用一个一个的对象描述对应起来,将问题集合分解为对象集合。实际中就是不断的问需要哪些服务,需要哪些对象才能履行它们的服务。良好的面向对象的设计中,每个对象都可以很好的完成一项任务,但是它并不试图做更多的事。


多态:


多态指的是在继承关系中子类继承父类的行为,这种行为在子类具体实现时可以是不一样的。比如动物这一父类中有move()方法,在鸟类子类中和鱼类子类中move的实现是不一样的。在Java中多态是通过重写(override:把父类的方法重新实现)和重载(overload:通过方法参数的不同在子类中来重新创建名字相同的方法)来实现的。

加载中
0
eechen
eechen
"万物皆对象",听着像邪教洗脑的口号.

且看Java大神王垠批判面向对象编程:

“对象思想”作为数据访问的方式,是有一定好处的。 然而“面向对象”(多了“面向”两个字),就是把这种本来良好的思想东拉西扯,牵强附会,发挥过了头。 很多面向对象语言号称“所有东西都是对象”,把所有函数都放进所谓对象里面,叫做“方法”,把普通的函数叫做“静态方法”。 实际上只有极少需要抽象的时候,需要使用内嵌于对象之内,跟数据紧密结合的“方法”。 其他的时候,你其实只是想表达数据之间的变换操作,这些完全可以用普通的函数表达,而且这样做更加简单和直接。 把所有函数放进对象的做法是本末倒置的,因为函数本身并不属于对象,它们只是对象上面的变换操作。 绝大部分函数是独立于对象的,它们不能被叫做“方法”。 强制把所有函数放进它们本来不属于的对象里面,把它们全都作为“方法”,导致了面向对象代码逻辑过度复杂。 很简单的想法,非得绕好多道弯子才能表达清楚。 很多人至今不知道自己所用的“面向对象语言”里面的很多优点,都是从过程式语言继承来的。

大多数的面向对象语言里都缺乏正确的实现一等函数的机制。 Java语言是一个极致,它完全不允许将函数当作数据来传递。 你需要将全部的函数都封装进类,然后称它们为“方法”,但就像我说的,这是绑架。 缺乏一等函数是为什么Java里需要这么多“设计模式”的主要原因。 一旦有了一等函数,你将不再需要大部分的这些设计模式。

编程最重要的事情,其实是让写出来的符号,能够简单地对实际或者想象出来的“世界”进行建模。 一个程序员最重要的能力,是直觉地看见符号和现实物体之间的对应关系。 不管看起来多么酷的语言或者范式,如果必须绕着弯子才能表达程序员心目中的模型,那么它就不是一个很好的语言或者范式。
(引用·完)

JS和PHP都可以将函数当作数据来传递,比如用哈希表来组织函数:
JS(用函数表组织函数,体现一等函数):
var func = {
    foo: function(arg){alert(arg);},
    bar: function(arg){alert(arg);}
};
func.foo('php');  //func['foo']('php');
func.bar('best'); //func['bar']('best');

PHP(面向数组编程:把函数和变量封装在数组内):
$func = array(
    'foo' => function($arg){echo $arg;},
    'bar' => function($arg){echo $arg;}
);
call_user_func($func['foo'], 'php');
call_user_func($func['bar'], 'best');

FlexSlider使用函数表(哈希表+匿名函数)组织内部函数:函数名为键,匿名函数为值.
PHP同样也可以把匿名函数封装在数组(哈希表)内,面向数组编程.


jquery.pjax.js在(function($){})(jQuery)里组织函数:
function foo(bar) { return bar; }
(function(){
    function foo(bar) { return bar; }
    console.log(foo("bar0")); //输出bar0
})();
console.log(foo("bar1")); //输出bar1

PHP中匿名函数里定义的非匿名函数是全局的,这点跟JS不同.
function foo($bar) { return $bar.__FUNCTION__; }
call_user_func(function(){
    //function foo($bar) { return $bar.__FUNCTION__; } //Fatal error: Cannot redeclare foo()
    echo foo('bar0')."\n";
});
echo foo('bar1')."\n"; //输出 bar1foo
所以可以这样:
$foo = function($bar) { return $bar.__FUNCTION__; };
call_user_func(function(){
    $foo = function($bar) { return $bar.__FUNCTION__; };
    echo $foo('bar0')."\n"; //输出 bar0{closure}
});
echo $foo('bar1')."\n"; //输出 bar1{closure}
0
w
wmj5467218

谢谢


分享            

0
中山野鬼
中山野鬼

引用来自“eechen”的评论

"万物皆对象",听着像邪教洗脑的口号.

且看Java大神王垠批判面向对象编程:

“对象思想”作为数据访问的方式,是有一定好处的。 然而“面向对象”(多了“面向”两个字),就是把这种本来良好的思想东拉西扯,牵强附会,发挥过了头。 很多面向对象语言号称“所有东西都是对象”,把所有函数都放进所谓对象里面,叫做“方法”,把普通的函数叫做“静态方法”。 实际上只有极少需要抽象的时候,需要使用内嵌于对象之内,跟数据紧密结合的“方法”。 其他的时候,你其实只是想表达数据之间的变换操作,这些完全可以用普通的函数表达,而且这样做更加简单和直接。 把所有函数放进对象的做法是本末倒置的,因为函数本身并不属于对象,它们只是对象上面的变换操作。 绝大部分函数是独立于对象的,它们不能被叫做“方法”。 强制把所有函数放进它们本来不属于的对象里面,把它们全都作为“方法”,导致了面向对象代码逻辑过度复杂。 很简单的想法,非得绕好多道弯子才能表达清楚。 很多人至今不知道自己所用的“面向对象语言”里面的很多优点,都是从过程式语言继承来的。

大多数的面向对象语言里都缺乏正确的实现一等函数的机制。 Java语言是一个极致,它完全不允许将函数当作数据来传递。 你需要将全部的函数都封装进类,然后称它们为“方法”,但就像我说的,这是绑架。 缺乏一等函数是为什么Java里需要这么多“设计模式”的主要原因。 一旦有了一等函数,你将不再需要大部分的这些设计模式。

编程最重要的事情,其实是让写出来的符号,能够简单地对实际或者想象出来的“世界”进行建模。 一个程序员最重要的能力,是直觉地看见符号和现实物体之间的对应关系。 不管看起来多么酷的语言或者范式,如果必须绕着弯子才能表达程序员心目中的模型,那么它就不是一个很好的语言或者范式。
(引用·完)

JS和PHP都可以将函数当作数据来传递,比如用哈希表来组织函数:
JS(用函数表组织函数,体现一等函数):
var func = {
    foo: function(arg){alert(arg);},
    bar: function(arg){alert(arg);}
};
func.foo('php');  //func['foo']('php');
func.bar('best'); //func['bar']('best');

PHP(面向数组编程:把函数和变量封装在数组内):
$func = array(
    'foo' => function($arg){echo $arg;},
    'bar' => function($arg){echo $arg;}
);
call_user_func($func['foo'], 'php');
call_user_func($func['bar'], 'best');

FlexSlider使用函数表(哈希表+匿名函数)组织内部函数:函数名为键,匿名函数为值.
PHP同样也可以把匿名函数封装在数组(哈希表)内,面向数组编程.


jquery.pjax.js在(function($){})(jQuery)里组织函数:
function foo(bar) { return bar; }
(function(){
    function foo(bar) { return bar; }
    console.log(foo("bar0")); //输出bar0
})();
console.log(foo("bar1")); //输出bar1

PHP中匿名函数里定义的非匿名函数是全局的,这点跟JS不同.
function foo($bar) { return $bar.__FUNCTION__; }
call_user_func(function(){
    //function foo($bar) { return $bar.__FUNCTION__; } //Fatal error: Cannot redeclare foo()
    echo foo('bar0')."\n";
});
echo foo('bar1')."\n"; //输出 bar1foo
所以可以这样:
$foo = function($bar) { return $bar.__FUNCTION__; };
call_user_func(function(){
    $foo = function($bar) { return $bar.__FUNCTION__; };
    echo $foo('bar0')."\n"; //输出 bar0{closure}
});
echo $foo('bar1')."\n"; //输出 bar1{closure}

你也是够了。。。java的东西虽然不熟,学过,也不用它,但是至少认为,它比较极致。极致带来的缺点确实有些形式化的东西,太繁琐。但不至于如c++那样,左也可以,右也可以。 所以,没必要这样“批判”java吧。

如果这样抬杠,我还觉得 php这种组织方式就是“一坨屎”。哈。 当然phper太牛逼了,不得罪phper们。

每个语言都有自己的特点。就独立的把局部特点抽出来比较语言并不合适。还是老话,要看应用场景,某个语言是否合适。

黑狗
黑狗
回复 @乌龟壳 : 哪个语言自己都有他的缺陷啊
乌龟壳
乌龟壳
java不能传递函数确实是个比较麻烦的事,不过最近几个版本都能变相传递了,确实证明以前这种设计是不够好的
0
醉酒舞剑砍疯子
全都是概念和定义
返回顶部
顶部