zoukankan      html  css  js  c++  java
  • 《Ruby语言入门教程v1.0》学习笔记-02

    9.18

    第四章 一切都是对象

    这个章节的例子都举得很浅显易懂,而且作者的语言= =噗,委实生动有趣啊是~~

    4.1  两种思维方式

    初期的编程思想是:以“如何做”为指导来编写代码。这时期的编程语言叫过程语言,提倡结构化地设计程序代码。代表语言是FORTRAN和C。
    现在的编程思想是:以“谁将被影响”为指导来编写代码。叫面向对象的编程语言,以类为模块,以消息来驱动程序的执行。代表语言是C++ 和Java。

    4.2  对象

    (这里是文摘。。。。摘摘摘摘摘。。。。。)

    每个事物都有一些特点,人有身高,体重,在程序中我们称之为属性;还可以有一些行为,人要吃饭,睡觉,在程序中我们称之为方法
    学生是人,自然有身高,体重,自然要吃饭,睡觉。如果你把人看作一类事物,把学生看作一类事物;那么,人是父类型,学生是子类型。子类型从父类型自然得到属性、方法,我们称之为继承
    学生要考试,工人不要;工人拿工资,学生不拿(一般而言)。同一个父类,不同的子类有不同的行为和状态,我们称之为多态
    人们编写程序,也就是在描述一类事物的特点(属性)、行为(方法)。有时候是模拟描述自然界中已有的一类事物,还有时候是创造地描述自然界中没有的一类事物。
    当人们决定了代码世界中一类事物的属性、方法,在代码世界中,这类事物的属性、方法只有定义代码的人知道,其它的类是不知道的。这就是封装
    封装、继承、多态是面向对象编程的三个本质特征。

    4.3  封装

    让我们来定义一个类,类名是Person,类名首字母要大写

    属性有姓名@name、年龄@age、国籍@motherland,实例变量用@开头

    方法有一个,叫talk, 方法名和参数名应该用一个小写字母开头或者用一个下划线开头

    举个例子吧~

    class Person
      def initialize( name, age=18 )     #initialize是初始化方法,相当于Java的构造器。参数age有一个缺省值18,可以在任何方法内使用缺省参数,而不仅仅是initialize。
        @name = name
        @age = age
        @motherland = "China"
      end #初始化方法结束
      def talk
        puts "my name is "+@name+", age is "+@age.to_s      #@age.to_s的含义是:将数@age转换为字符串。
        if @motherland == "China"
          puts "I am a Chinese."
        else
          puts "I am a foreigner."
        end
      end # talk方法结束
    attr_writer :motherland            #相当于def motherland=(value); return @motherland =value; end

    end # Person类结束

    p1=Person.new("kaichuan",20);p1.talk

    p2=Person.new("Ben");p2.motherland="ABC";p2.talk

    #my name is kaichuan, age is 20
    I am a Chinese.
    my name is Ben, age is 18
    I am a foreigner.

    4.4   继承

    class Student < Person             #用“ < ”表示Student类是 Person类的子类。
      def talk                                #Student类继承Person类的一切,而这里Student类重写了talk方法。
        puts "I am a student. my name is "+@name+", age is "+@age.to_s  #子类继承父类的时候,除了重写方法;也可以添加一些新的方法;或是增强父类的方法(用关键字super指明)。
      end # talk方法结束
    end # Student类结束
    p3=Student.new("kaichuan",25); p3.talk
    p4=Student.new("Ben"); p4.talk
    #I am a student. my name is kaichuan, age is 25
    I am a student. my name is Ben, age is 18

    注意:如果子类不重新定义方法的话,会默认该子类使用父类的方法。另,所有新增的类都是属于Ruby语言中已经定义了的Object类,如果你在定义新类的时候,没有指明新类的父类,那么,Ruby解释器认为,新类的父类是Object类。类Object含有new方法、initialize方法…只要你不重写这些方法,你就自然在使用类Object的方法。

    说个好玩儿的,在这一节的后面有这样一段话,实在是有趣啊~哈哈哈哈哈~~~

    一个实例生成了,又一个实例生成了…他们或许是同类型的,或许不是同类型的,或许是有亲缘关系的。无数的实例在代码世界中交互、缠结,忽生忽死,无休无止…

    4.5  多态

    多态在这里就不多说了,其实就是不同子类的多样性,基本来说,我的理解就是,他们定义的方法不同,或者是数目不同,或者是同一名称的方法的内容不同。

    这里要注意的是,“Ruby语言,只有重写(override),没有其它语言具有的严格意义上的重载(overload)”。

    9.26

    第五章

    5.3 详解变量—— 动态类型

    在ruby当中,变量和方法区分的并不明显。变量要有的特性:#只抽出了需要的两点

    1). 变量有名字;
    2).变量代表的那个事物应该有一个可以用数学度量的值;长度,面积,速度大小,磁场强度…

     在 Java 中,编译的时候,就完成了类型匹配的检测,这属于前期绑定; Ruby 是在运行中检测,检测类型匹配吗?不是检测类型匹配,而是检测语法,只要与语法定义不矛盾,就能通过。这样成就了方便,也造就了麻烦,如果变量的命名不清晰明了,就容易出现错误。“如何避免常常出错呢?有一个下口之处,就是死盯住变量的命名。用一些有意义的名字,不必太长,但是应该少用单字符,除非是循环指针变量。你也许认为我自己能看懂就行了,这是十分有害的想法。在一个项目组中,程序员是要彼此相互沟通合作的。当坏习惯养成后,要改是很难的。

    Ruby中“方法”的增删改#举例删除,修改也是同样,重新在类里定义方法就好

    class Person
      def talk
        puts "Today is Saturday. "
      end
    end

    p1=Person.new
    p1.talk   # Today is Saturday.

    class Person

       undef :talk

    end   #p1.talk talk方法已经不存在

    5.5 一些编码建议

    # 题外话,果然有txt就是好啊,清除格式什么的最好用了,从别的地方复制过来的文档总有些奇奇怪怪的格式,更坑爹的是还有可能影响到其它文本,所以粘贴过来前先放txt里面净化一遍真是太好了啊~~

    一. 命名
    常量全用大写的字母,用下划线分割单词。例如:MAX, ARRAY_LENGTH。
    类名和模块名大写字母开头的单词组合而成。例如:MyClass, Person。
    方法名全用小写的字母,用下划线分割单词。例如:talk, is_prime?。在Ruby里,有时将“!”和“?”附于某些方法名后面。

        惊叹号“!”暗示这个方法具有破坏性, 有可能会改变传入的参数。问号“?”表示这个方法是一个布尔方法,只会返回 true 或 false。

    变量和参数小写字母开头的单词组合而成。例如:name, currentValue。
    类名、模块名、变量名、参数名最好使用“名词”或者“形容词+名词”。

    方法名最好使用“动词”或者“动词+名词”。例如:aStudent.talk 。

    二. 空格和圆括号
    关键字之后要留空格。
    逗号“,”、 分号“;”之后要留空格。 “,”、 “;”向前紧跟,紧跟处不留空格。
    赋值操作符、比较操作符、算术操作符、逻辑操作符,如“=”、“+=” “>=”、“<=”、“+”、“*”、“%”、“&&”、“||”等二元操作符的前后应当加空格。
    一元操作符如“!”、“~”等之后不加空格。
    “[]”、“.”、“::”这类操作符前后不加空格。
    函数名之后不要留空格,紧跟左圆括号“(”,以与关键字区别。左圆括号“(”向后紧跟,右圆括号“)”向前紧跟,紧跟处不留空格。

    #只要不会造成逻辑错误神马的,圆括号()基本可以省略。

    三. 使用 return
    你在定义方法的时候,在最后一行可以显式地 return 某个值或几个值,但却不是必须的。 Ruby 方法的最后一行语句如果是表达式,表达式的值会被自动返回;最后一行语句如果不是表达式,就什么也不返回。

    第六章 深入面象对象

    6.1 重载?重写

    重载      4.5节说到:“ Ruby语言,只有重写,没有其它语言具有的严格意义上的重载。” 下面仔细分析 Ruby 为何没有重载,只有重写。

    Ruby支持缺省参数,我们看程序 E6.1-1.rb :
    def sum( a, b=5 )
        a+b
    end
    puts sum(3,6)    #9   
    puts sum(3)       #8   二者在Java中是调用不同方法,但在Ruby中是调用同一个。

    Ruby还支持可变参数,我们看程序 E6.1-2.rb :
    def sum( *num )
        numSum = 0
        num.each { |i| numSum+=i }
        return numSum
    end
    puts sum()                             #0
    puts sum(3,6)                        #9
    puts sum(1,2,3,4,5,6,7,8,9)   #45

    #由于缺省参数和可变参数,参数个数不同而产生的重载,在Ruby中不再有效。

    重写

    在子类和父类中,如果子类里不写该方法,那么就是直接集成父类;如果是子类重新写了该方法,那就是执行子类当中的方法。

    写在同一个类中的不同方法,总是写在后面的方法被实现。

    6.2 增强父类方法

    之前一直搞不懂增强父类的方法是什么(喂喂,提前暴露自己学校没好好学了吧= =||),咳咳,原来意思是说,以子类身份执行方法时,除了执行父类方法,还会执行子类中该方法添加的部分。

    class Person
      def talk(name)
        print "my name is #{name}."
      end
    end
    class Student < Person
      def talk(name)
        super
        print "and I'm a student. "   
      end
    end
    aPerson=Person.new             #只执行父类中输出姓名
    aPerson.talk("kaichuan")        #my name is kaichuan.
    aStudent=Student.new         #除了执行父类中的输出姓名,还执行子类中的super增强部分。
    aStudent.talk("kaichuan")      #my name is kaichuan.and I'm a student.

    # 之前有想过,其实在子类中重写方法也是一样的嘛,而且更清晰。但是再一想,如果量啊逻辑啊神马的比较麻烦,那还是这样好了,更简单一些~~

    6.3 实例变量、类变量、类方法

    如果一个变量,其作用域遍及在程序的任何位置,这样的变量称之为全局变量;与之相对,作用域仅限于在程序的某一单元的变量,称之为局部变量

    如果一个变量,只能被某个实例对象使用,这样的变量称之为实例变量;如果一个变量,能被某个类的所有实例对象共享,这样的变量称之为类变量

    常量可以定义在类和模块中,不能定义在方法中(方法中只能对变量进行赋值,或者设置变量的缺省值。)。如果在外部访问类或模块中的常量,要使用域作用符::

    全局变量$ 开头。

    实例变量,变量名用@ 开头;类变量,变量名用@@ 开头.

    Ruby中所说的局部变量,可以是存在于类中、方法中、模块中、一个循环中、一个过程对象中。局部变量名用小写字母开头。

    实例变量:譬如类Student,学生Jmy是一个实例,那么@name、@age、@motherland,都是实例变量,被每个实例独享。

    类变量:譬如类Class0901,学生Jmy是一个实例,@@count(班级人数)是类变量,被class0901类里所有实例共享。

    class StudentClass
        @@count=0
        def initialize( name )
            @name = name
            @@count+=1
        end
        def talk
            puts "I am #@name, This class have #@@count students."
        end
    end
    p1=StudentClass.new("Student 1 ")
    p2=StudentClass.new("Student 2 ")
    p3=StudentClass.new("Student 3 ")
    p4=StudentClass.new("Student 4 ")
    p3.talk # I am Student 3 , This class have 4 students.
    p4.talk # I am Student 4 , This class have 4 students.

    class StudentClass 

        @@count=0
        def initialize
            @@count+=1
        end
        def StudentClass.student_count
            puts "This class have #@@count students."
        end
    end
    p1=StudentClass.new
    p2=StudentClass.new
    StudentClass.student_count     # This class have 2 students.
    p3=StudentClass.new
    p4=StudentClass.new
    StudentClass.student_count     # This class have 2 students.

    #调用一个类方法,与定义类方法一样,要在方法名前加上类名和一个点号“.”。类方法提供了一个途径,在类的外部访问类变量,无须通过类的实例方法。

    #调用类方法,不需要依赖于任何实例的方法

    10.08

    6.4 单例方法

    class Person
        def talk
            puts "Hi! "
        end
    end


    p1=Person.new
    p2=Person.new


    def p2.talk           #定义单例方法p2.talk
        puts "Here is p2. "
    end
    def p2.laugh       #定义单例方法p2. laugh
        puts "ha,ha,ha... "
    end


    p1.talk                # Hi!
    p2.talk                # Here is p2.
    p2.laugh             # ha,ha,ha...

      在Ruby里,可以给具体的实例对象添加实例方法,这个方法只属于这个实例对象,我们把这样的方法称之为单例方法

      定义单例方法,首先要生成一个实例对象;

      其次,要在方法名前加上对象名和一个点号“.”。

      左图程序中,对象p1不可以laugh , laugh方法只属于p2对象。

    6.5 访问控制

    控制对方法的访问,有三种方式:

    Public        可以被任何实例对象调用,不存在访问控制;

    Protected  可以被定义它的类和其子类访问,可以在类中或子类中指定给实例对象;

    Private      可以被定义它的类和其子类访问,不能被实例对象调用。

    Public 方法默认都是公有的( initialize方法除外,它永远是私有的)。

    class Person
        def talk
            puts " public :talk, 将调用speak"
            speak
        end
        def speak
            puts "protected :speak,将调用laugh"
            laugh
        end
        def laugh
            puts " private:laugh"
        end
        protected :speak #实例对象不能调用protected方法
        private :laugh      #实例对象不能调用private方法
    end

    p1=Person.new
    p1.talk      #public :talk, 将调用speak

                       protected:speak,将调用laugh

                       private:laugh

    p1.speak #protected method 'speak’ 

    p1.laugh  #prrivate method 'laugh’

    class Person
        def speak
            "protected:speak "
        end
        def laugh
            " private:laugh"
        end
        protected :speak
        private :laugh
    end


    class Student < Person
        def useLaugh
            puts laugh
        end
        def useSpeak
            puts speak
        end
    end


    p2=Student.new
    p2. useLaugh       # private:laugh
    p2. useSpeak       # protected:speak

    class Person
        def speak
            "protected:speak "
        end
        def laugh
            " private:laugh"
        end
        protected :speak
        private :laugh
        def useLaugh(another)
            puts another.laugh   
        end
        def useSpeak(another)
            puts another.speak
        end
    end

    p1=Person.new
    p2=Person.new

    def p1.speak

        puts"I am p1."

    end

    p2.useSpeak(p1)     # I am p1.

  • 相关阅读:
    单机RedHat6.5+JDK1.8+Hadoop2.7.3+Spark2.1.1+zookeeper3.4.6+kafka2.11+flume1.6环境搭建步骤
    kafka_2.11-0.8.2.1+java 生产消费程序demo示例
    Kafka使用log.retention.hours改变消息端的消息保存时间
    Apache Kafka监控之KafkaOffsetMonitor
    Apache Kafka监控之Kafka Web Console
    Kafka三款监控工具比较
    linux查看本机IP、gateway、dns
    kafka_2.11-0.8.2.1生产者producer的Java实现
    linux下杀死进程(kill)的N种方法
    Linux查看硬件配置命令
  • 原文地址:https://www.cnblogs.com/poppyp/p/3324470.html
Copyright © 2011-2022 走看看