精华内容
参与话题
问答
  • 什么是面向对象程序设计

    万次阅读 2019-08-22 11:10:04
    1.面向对象和面向过程区别→2.什么是对象→3.什么是消息→4.什么是封装→5....面向过程程序设计:所谓的面向过程程序设计就是函数的定义和调用。简单地说,过程就是程序执行某项操作的一段代码,函...

    目录(可以点击相应标题快速定位)

    1.面向对象和面向过程区别 → 2.什么是对象 → 3.什么是消息 → 4.什么是封装→ 5.什么是多态 → 6.面向对象的优点:


    本文介绍 C++基础概念和知识。如果您想看其他语言(如 java)的语法,本文不涉及。

    1.面向对象和面向过程区别

    面向过程程序设计:所谓的面向过程程序设计就是函数的定义和调用。简单地说,过程就是程序执行某项操作的一段代码,函数是最常用的过程。

    面向对象程序设计:面向对象程序设计就是对象加消息。第一,程序一般由类的定义和使用两部分组成,而类的实例即对象;第二,程序中的一切操作都是通过对象发送消息来实现的,对象接收消息后,启动有关方法完成相应的操作。

    2.什么是对象

    对象可以理解为:用现实生活中来表述是属性+行为,用程序语言来表述是数据(变量)+操作(函数);

    对象需要有以下四点特征:

    ①每一个对象必须有一个名字以区别与其他对象(类的实例)。对于对象来说,每一个对象的数据成员都有其自己独立的存储空间,不同对象的数据成员占有不同的存储空间,而不同对象的成员函数是占有同一个函数代码段的。

    ②用属性来描述他的某些特征(数据赋值)。

    ③有一组操作,每个操作决定对象的一种行为(函数调用)。

    ④对象的操作可以分为两类:一类是自身所承受的操作,另一类是施加于其他对象的操作。

    3.什么是消息 

    一个对象与另一个对象之间的交互称之为消息。对象之间的联系只能通过消息传递来进行,且具有以下 3 个性质:

    ①同一个对象可以接收不同形式的多个消息,做出不同的相应。

    ②相同形式的消息可以传递给不同的对象,所做出的相应可以是不同的。

    ③对消息的相应并不是必须的,对象可以响应消息,也可以不响应。

    实现消息传递的方法:

    调用对象中的函数就是向该对象传送一个消息,要求该对象实现某一行为(功能、操作)。对象所能实现的行为(操作),在程序设计中成为方法,他们是通过调用相应的函数(C++中成为成员函数)来实现的。

    #include <iostream>
    
    class ABC
    {
    public:
        void init(int i, int j)  //对应  2.中的③
        { a = i; b = j; }
        void show()
        { std::cout << a << "  " << b << std::endl; }
    private:
        int a, b;          //对应 2.中的②
    };
    
    int main()
    {
        ABC o1, o2;         //类的两个实例即对象;  对应 2.中的①
        o1.init(12, 34);    //对象的消息传递;
        o2 = o1;            //对象之间的消息传递; 
        o1.show();          //同一对象接收多个消息;对应3.中的①
        o2.show();          //不同对象接收同一消息;对应3.中的②
        return 0;
    }
    
    //output:
    //12  34
    //12  34

    4.什么是封装

    封装就是把数据和实现操作的代码(函数)集中起来放在对象内部(类),并尽可能的屏蔽对象的内部细节,不能从外部直接访问或修改这些数据(如类中的 private 数据)及代码(如类中函数的代码在外部调用函数时是不可以修改的,是能使用其提供的功能)。使用一个对象的时候只需要知道它向外界提供的接口形式(函数名+参数)而无需知道他的数据结构细节和实现操作的算法。

    封装的含义:一是将有关的数据和操作代码封装在一个对象中,各个对象相互独自、互不干扰。而是将对象中的某些数据与操作代码对外隐藏,只留下少量接口,以便于外界联系,接收外界消息。

    5.什么是多态

    多态是指不同的对象收到相同的消息时产生多种不同的行为方式。C++支持两种多态性,即编译时的多态性(重载:函数/运算符重载)和运行时的多态性(虚函数)。

    关于虚函数的相关内容可以点击:https://blog.csdn.net/qq_41291253/article/details/100079861

    6.面向对象的优点:

    ①提高程序可重用性:通过继承

    ②改善程序可维护性:不改变接口而维护接口内部程序实现,不影响用户。

    ③跟好的支持大型程序设计:分模块设计,做自己的接口,然后整合到一个系统中去。

    展开全文
  • JAVA面向对象编程

    千次阅读 2018-09-06 19:10:16
    目录 1.构造方法: 2.this 3.继承 4.父类 5.重写 6.重载 7.访问修饰符 8.单例的实现 9.修饰符:static,final,abstract 10.interface 接口 11.开闭原则: 12.内部类 特征:封装,继承,多态... 1.... 2....

     

    目录

    1.构造方法:

    2.this

    3.继承

    4.父类

    5.重写

    6.重载

    7.访问修饰符

    8.单例的实现

    9.修饰符:static,final,abstract

    10.interface  接口

    11.开闭原则:

    12.内部类

    特征:封装,继承,多态(,抽象)

    1.构造方法:

    构造器:
      构造方法(构造函数)
      1.构造器名称和类名一致
      2.没有返回值类型(8种基本类型,String,引用类型,void)
      3.一个类中可以有多个构造器,多个构造器靠参数列表(个数,顺序,类型)来区分
      4.构造器的调用:当类被实例化时调用(new)--通过(名+参数列表)调用
      5.如果你不给这个类提供构造器,JVM会给该类提供一个默认的无参的构造器
        如果你给这个类提供构造器,JVM不会给该类提供一个默认的无参的构造器
      作用:
      为了初始化对象方便,更合理的初始化对

    2.this

    this:当前类对象
      1. this.       
        当前类的属性和当前类的方法
     2. this()
         当前的构造器,只能写在构造器的第一句

    3.继承

         1 .A is B(A是B)
         2.关系是相对的
         3.java中只支持单继承

    4.父类

    super:父类的对象
     1. super.
               能调用父类的属性和父类的方法
     2. super()
        调用父类的构造--通过参数列表
        只能写在构造器的第一句

    5.重写

    重写:
          1.存在继承关系的两个类中方法
          2.方法的名称一样,参数列表一样,返回类型也一样

    6.重载

           在同一个类中的多个方法,方法的名称相同,参数列表不相同,返回类型无所谓

    7.访问修饰符

    1)、public, private, protected,默认都可修饰成员变量,成员方法。

    2)、public,默认 可修饰顶层类。

    3)、局部变量不能用访问修饰符。

    4)成员变量或成员方法的访问控制:

    位置

    private

    默认

    protected

    public

    同一个类

    同一个包内的类

    不同包内的子类

    不同包并且不是子类

    8.单例的实现

    单例:实例化出来的对象是同一个对象

    方法:写一个私有的,静态的构造

    1、通过静态方法实现

    代码:

    Public class Run{
    
           private static Run r=null;
    
           public static Run gerRun(){
    
                    if(r==null){
    
                              r=new Run();
    
    }
    
    Return r;
    
    }
    
    }
    
    Public class Transfer{
    
           Public static void main(String[] args){
    
                    Run ru=Run.getRun();
    
                    Sysetem.out.printlin(ru);
    
                    Run ru1=Run.getRun();
    
                    Sysetem.out.printlin(ru1);
    
    
    
    }
    
    }

    运行结果:

    Run @4554617c

    Run @4554617c

    2、通过静态块实现

    public class demo02 {
    
        private static demo02 d=null;
    
        static {
    
            if(d==null){
    
                d=new demo02();
    
            }
    
        }
    
        public static demo02 getdemo02(){
    
            return d;
    
        }
    
     public class demo01 {
    
        public static void main(String[] args) {
    
            demo02 d1=demo02.getdemo02();
    
            System.out.println(d1);
    
            demo02 d2=demo02.getdemo02();
    
            System.out.println(d2);
    
    
    
        }
    
    }
    运行结果:

    Run @4554617c

    Run @4554617c

    9.修饰符:static,final,abstract

    (一)static-静态

    1.static能修饰属性,方法,静态块

    2.static修饰的属性:是多个对象共有的一块空间

    3.static修饰属性,方法--可以不通过实例化对象得到,可以通过类名直接调用

    4.静态方法和静态块中只允许使用静态属性

    5.静态块是在类被加载时调用

    (二)final:常量

     1.final能修饰变量,方法,类

    2.final修饰变量:不能被第二次赋值

    3.final修饰方法:不能被重写

    4.final修饰类:不能被继承

    (三)abstract :抽象类

    1.用abstract 修饰的类就是抽象类

    2.抽象类中可以有属性,方法,还可以有抽象方法

            抽象方法:

                   A.用abstract 修饰的方法就是抽象方法

                   B.抽象方法只有方法的声明,没有方法的实现(没有{})

    3.抽象类不能实例化(new)

    4.使用: 用一个类去继承抽象类,并把这个抽象类中的所有抽象方法都“重写“,否则该类还是为抽象类

    5.可以有构造方法,只是不能实例化

    代码示例:

    //通过父类声明,子类实例化来使用这个抽象类
    public class Test{
        public static void main(String[] args){
            Person p=new Person_C();
            p.say();
            System.out.println(p.i);
        }
    }
    
    //由于抽象类不能实例化,通过继承实现抽象类,将所有抽象方法重写
    public class Person_C extends Person{
        public  void say(){
            System.out.println("你好");
        }
    }
    

     

    //抽象类,可以有属性,方法,抽象方法
    public abstract class Person{
        public int i=1;
        public abstract void say();
    }

     

    10.interface  接口

    1.用interface修饰的东西就是接口

    2.接口中可以有属性

                接口中默认的属性类型为public  static  final类型(可省略)

    3.接口中只能有方法的声明(或者抽象方法),不能有方法的实现

    4.接口不能被实例化

    5.用一个类去“实现”一个接口,实现的关键字是implements

       实现接口时必须把所有的方法声明都实现,否则该类是一个抽象类

    6.一个类可以实现多个接口,A extends B implements C,D,E

    7.接口允许多继承

    代码示例:

    //用iterface修饰的就是接口
    public interface Tools1{
        float G=9.8f;
    //public static final float G=9.8;接口中的属性默认为public static final类型,可以省略
    //接口中可以有方法的声明(或者抽象方法),不能有方法的实现
        public void usb();
    //接口中不能有构造方法
    }
    public interface Tools2{
        float PI=3.141592653f;
        public void circle(int r);
    }

     实现方式一: 

    //用一个类去“实现”接口需要有implement关键字,接口可以多继承
    public class PC implement Tools1,Tools2{
        //要对接口中的所有方法实现重写,否则该类是一个抽象类
        @override
        public void usb(){
            System.out.println("PC's usb.")
        }
        @override
        public void circle(int a){
            System.out.println(2*a*PI);
        }
    }

     实现方式二:

    //一个类可以实现多个接口
    public class Test1 extends Demo implements Tools1,Tools2{
        public static void main(String[] args) {
            Test1 t=new Test1();
            t.circle(15);
            t.usb();
    
        }
        @Override
        public void usb() {
            System.out.println("usb()");
        }
    
        @Override
        public void circle(int r) {
            System.out.println(2*r*PI);
        }
    }

     

     

    补充:满足继承关系的时候使用抽象类,不满足抽象关系的时候使用接口,但是我们日常工作中都使用的是接口。

    11.开闭原则:

    对扩展(继承,接口)开发,对修改关闭

    12.内部类

    代码示例:

    public class A {
        int a=10;
    //    内部类的实例化:内部类不能直接被实例化,在外部类实例化一个内部类对象
        public B bbb=new B();
        public void say(){
            System.out.println("...A...say()...");
        }
        class B{
            int b=100;
            public void say(){
                System.out.println("...B...say()...");
            }
        }
    }
    public class Test {
        public static void main(String[] args) {
            A aaa=new A();
    //        内部类的调用
            aaa.bbb.say();
            System.out.println(aaa.bbb.b);
        }
    }

    父类声明,子类实例化的特点:

          对象是父类的对象,能调用父类的属性和方法,也能调用子类重写父类的方法

     

     

     

     

    展开全文
  • 面向对象编程(Python版详解)

    千次阅读 多人点赞 2020-04-03 14:14:18
    面向对象编程介绍二.类和对象三.类的构成 一.面向对象编程介绍 如今主流的软件开发思想有两种:一个是面向过程,另一个是面向对象。面向过程出现得较早,典型代表为C语言,开发中小型项目的效率很高,但是很难适用...

    python版,面向对象编程分三篇给大家介绍,这是第一篇,欢迎阅读学习,一起进步




    一.面向对象编程介绍

    • 如今主流的软件开发思想有两种:一个是面向过程,另一个是面向对象。面向过程出现得较早,典型代表为C语言,开发中小型项目的效率很高,但是很难适用于如今主流的大中型项目开发场景。面向对象则出现得更晚一些,典型代表为Java或C++等语言,更加适合用于大型开发场景。两种开发思想各有长短。
    • 对于面向过程的思想: 需要实现一个功能的时候,看重的是开发的步骤和过程,每一个步骤都需要自己亲力亲为,需要自己编写代码(自己来做)
    • 对于面向对象的思想:当需要实现一个功能的时候,看重的并不是过程和步骤,而是关心谁帮我做这件事(偷懒,找人帮我做)
    • 面向对象的三大特征有:封装性、继承性、多态性。

    生活举例

    • 洗衣服

    • 面向过程(手洗):脱衣服、找一个盆、加水、加洗衣粉、浸泡30分钟、搓洗、拧衣服、倒掉水、再加水、漂洗、拧衣服、倒掉水、晾衣服。

    • 面向对象(机洗):脱衣服、放入洗衣机、按下开关、拿出衣服晾晒。

    • 买电脑

    • 面向过程(自己买):需要电脑、查询参数信息、横向比较机型、了解打折信息、与店家讨价还价、下单、收快递、开机验货、确认收货。

    • 面向对象(找人买):需要电脑、找秘书帮我买、收电脑。


    二.类和对象

    面向对象编程的2个非常重要的概念:类和对象

    • 对象是面向对象编程的核心,在使用对象的过程中,为了将具有共同特征和行为的一组对象抽象定义,提出了另外一个新的概念——类
    • 面向对象的语言当中,“类”就是用来模拟现实事物的。
    • 类:抽象的,是一张“手机设计图”。
    • 对象:具体的,是一个“真正的手机实例”。

    在这里插入图片描述

    • 小结:类是抽象的,在使用的时候通常会找到这个类的一个具体的存在,使用这个具体的存在。一个类可以找到多个对象。

    人以类聚 物以群分。
    具有相似内部状态和运动规律的实体的集合(或统称为抽象)。
    具有相同属性和行为事物的统称

    • 类就相当于制造飞机时的图纸,用它来进行创建的飞机就相当于对象 类是一类事物,对象即是这类事物实现

    在这里插入图片描述

    • 类中也有属性、行为两个组成部分,而“对象”是类的具体实例
    • 属性:事物的特征描述信息,用于描述某个特征“是什么”。
    • 行为:事物的能力行动方案,用于说明事物“能做什么”。

    三.类的构成

    • 类(Class) 由3个部分构成
    类的名称:类名
    类的属性:一组数据
    类的方法:允许对进行操作的方法 (行为)
    
    • 案例
    1)人类设计:
    
    事物名称(类名):(Person)
    属性:身高(height)、年龄(age)
    方法(行为/功能):(run)、打架(fight)
    
    2)狗类的设计
    
    类名:(Dog)
    属性:品种 、毛色、性别、名字、 腿儿的数量
    方法(行为/功能):叫 、跑、咬人、吃、摇尾巴
    
    • 类的抽象
    • 如何把日常生活中的事物抽象成程序中的类?
    • 拥有相同(或者类似)属性和行为的对象都可以抽像出一个类
    • 方法:一般名词都是类(名词提炼法)

    案例:坦克发射3颗炮弹轰掉了2架飞机

    • 坦克—可以抽象成类
    • 炮弹—以抽象成类
    • 飞机—可以抽象成类

    案例:如下植物大战僵尸可以抽象为几个类

    在这里插入图片描述

    向日葵
    类名: xrk
    属性: 颜色
    行为: 放阳光
    
    豌豆
    类名: wd
    属性: 颜色 、发型,血量
    行为:发炮, 摇头
    
    坚果:
    类名:jg
    属性:血量 类型
    行为:阻挡;
    
    僵尸:
    类名:js
    属性:颜色、血量、 类型、速度
    行为:走 跑跳 吃 死
    

    四.定义类 和 创建对象

    • 定义一个类,格式如下:
    class 类名:
        方法列表
    
    • demo:定义一个Hero类
    # class Hero:  # 经典类(旧式类)定义形式
    # class Hero():
    
    class Hero(object):  # 新式类定义形式
        def info(self):
            print("英雄各有见,何必问出处。")
    
    • 说明:
    • ①定义类时有2种形式:新式类和经典类,上面代码中的Hero为新式类,前两行注释部分则为经典类;
    • ②object 是Python 里所有类的最顶级父类;
    • ③类名 的命名规则按照"大驼峰命名法"
    • ④info 是一个实例方法,第一个参数一般是self,表示实例对象本身,当然了可以将self换为其它的名字,其作用是一个变量这个变量指向了实例对象

    • python中,可以根据已经定义的类去创建出一个或多个对象。
    • 创建对象的格式为:
    对象名1 = 类名()
    对象名2 = 类名()
    对象名3 = 类名()
    
    • 创建对象demo:
    class Hero(object):  # 新式类定义形式
        """info 是一个实例方法,类对象可以调用实例方法,实例方法的第一个参数一定是self"""
        def info(self):
            """当对象调用实例方法时,Python会自动将对象本身的引用做为参数,
                传递到实例方法的第一个参数self里"""
            print(self) 
            print("self各不同,对象是出处。")
    
    
    # Hero这个类 实例化了一个对象  taidamier(泰达米尔)
    taidamier = Hero()
    
    # 对象调用实例方法info(),执行info()里的代码
    # . 表示选择属性或者方法
    taidamier.info()
    
    print(taidamier)  # 打印对象,则默认打印对象在内存的地址,结果等同于info里的print(self)
    print(id(taidamier))  # id(taidamier) 则是内存地址的十进制形式表示
    
    <__main__.Hero object at 0x036EB0D0>
    self各不同,对象是出处。
    <__main__.Hero object at 0x036EB0D0>
    57585872
    
    • 小结:当创建一个对象时,就是用一个模子,来制造一个实物

    五.对象属性获取

    对象既然有实例方法,是否也可以有自己的属性?

    • 添加和获取对象的属性
    class Hero(object):
        """定义了一个英雄类,可以移动和攻击"""
        def move(self):
            """实例方法"""
            print("正在前往事发地点...")
    
        def attack(self):
            """实例方法"""
            print("发出了一招强力的普通攻击...")
    
    # 实例化了一个英雄对象 泰达米尔
    taidamier = Hero()
    
    # 给对象添加属性,以及对应的属性值
    taidamier.name = "泰达米尔"  # 姓名
    taidamier.hp = 2600  # 生命值
    taidamier.atk = 450  # 攻击力
    taidamier.armor = 200  # 护甲值
    
    # 通过.成员选择运算符,获取对象的属性值
    print("英雄 %s 的生命值 :%d" % (taidamier.name, taidamier.hp))
    print("英雄 %s 的攻击力 :%d" % (taidamier.name, taidamier.atk))
    print("英雄 %s 的护甲值 :%d" % (taidamier.name, taidamier.armor))
    
    # 通过.成员选择运算符,获取对象的实例方法
    taidamier.move()
    taidamier.attack()
    
    英雄 泰达米尔 的生命值 :2600
    英雄 泰达米尔 的攻击力 :450
    英雄 泰达米尔 的护甲值 :200
    正在前往事发地点...
    发出了一招强力的普通攻击...
    

    对象创建并添加属性后,能否在类的实例方法里获取这些属性呢?如果可以的话,应该通过什么方式?

    • 在方法内通过self获取对象属性
    class Hero(object):
        """定义了一个英雄类,可以移动和攻击"""
        def move(self):
            """实例方法"""
            print("正在前往事发地点...")
    
        def attack(self):
            """实例方法"""
            print("发出了一招强力的普通攻击...")
    
        def info(self):
            """在类的实例方法中,通过self获取该对象的属性"""
            print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
            print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
            print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))
    
    
    # 实例化了一个英雄对象 泰达米尔
    taidamier = Hero()
    
    # 给对象添加属性,以及对应的属性值
    taidamier.name = "泰达米尔"  # 姓名
    taidamier.hp = 2600  # 生命值
    taidamier.atk = 450  # 攻击力
    taidamier.armor = 200  # 护甲值
    
    # 通过.成员选择运算符,获取对象的实例方法
    taidamier.info()  # 只需要调用实例方法info(),即可获取英雄的属性
    taidamier.move()
    taidamier.attack()
    
    英雄 泰达米尔 的生命值 :2600
    英雄 泰达米尔 的攻击力 :450
    英雄 泰达米尔 的护甲值 :200
    正在前往事发地点...
    发出了一招强力的普通攻击...
    

    六.魔法方法__init__()

    创建对象后再去添加属性有点不合适,有没有简单的办法,可以在创建对象的时候,就已经拥有这些属性?

    class Hero(object):
        """定义了一个英雄类,可以移动和攻击"""
        # Python 的类里提供的,两个下划线开始,两个下划线结束的方法,就是魔法方法,__init__()就是一个魔法方法,通常用来做属性初始化 或 赋值 操作。
        # 如果类面没有写__init__方法,Python会自动创建,但是不执行任何操作,
        # 如果为了能够在完成自己想要的功能,可以自己定义__init__方法,
        # 所以一个类里无论自己是否编写__init__方法 一定有__init__方法。
    
        def __init__(self):
            """ 方法,用来做变量初始化 或 赋值 操作,在类实例化对象的时候,会被自动调用"""
            self.name = "泰达米尔" # 姓名
            self.hp = 2600 # 生命值
            self.atk = 450  # 攻击力
            self.armor = 200  # 护甲值
    
        def info(self):
            """在类的实例方法中,通过self获取该对象的属性"""
            print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
            print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
            print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))
    
        def move(self):
            """实例方法"""
            print("正在前往事发地点...")
    
        def attack(self):
            """实例方法"""
            print("发出了一招强力的普通攻击...")
    
    
    # 实例化了一个英雄对象,并自动调用__init__()方法
    taidamier = Hero()
    
    # 通过.成员选择运算符,获取对象的实例方法
    taidamier.info() # 只需要调用实例方法info(),即可获取英雄的属性
    taidamier.move()
    taidamier.attack()
    
    英雄 泰达米尔 的生命值 :2600
    英雄 泰达米尔 的攻击力 :450
    英雄 泰达米尔 的护甲值 :200
    正在前往事发地点...
    发出了一招强力的普通攻击...
    

    • 有参数的__init__()方法
    class Hero(object):
        """定义了一个英雄类,可以移动和攻击"""
    
        def __init__(self, name, skill, hp, atk, armor):
            """ __init__() 方法,用来做变量初始化 或 赋值 操作"""
            # 英雄名
            self.name = name
            # 技能
            self.skill = skill
            # 生命值:
            self.hp = hp
            # 攻击力
            self.atk = atk
            # 护甲值
            self.armor = armor
    
        def move(self):
            """实例方法"""
            print("%s 正在前往事发地点..." % self.name)
    
        def attack(self):
            """实例方法"""
            print("发出了一招强力的%s..." % self.skill)
    
        def info(self):
            print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
            print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
            print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))
    
    
    # 实例化英雄对象时,参数会传递到对象的__init__()方法里
    taidamier = Hero("泰达米尔", "旋风斩", 2600, 450, 200)
    gailun = Hero("盖伦", "大宝剑", 4200, 260, 400)
    
    # 直接输出对象即为地址
    print(gailun)
    # <__main__.Hero object at 0x0318B100>
    print(taidamier)
    # <__main__.Hero object at 0x0318B0D0>
    
    # 不同对象的属性值的单独保存
    print(id(taidamier.name))
    print(id(gailun.name))
    
    # 同一个类的不同对象,实例方法共享
    print(id(taidamier.move()))
    # 泰达米尔 正在前往事发地点...
    # 2045877480
    print(id(gailun.move()))
    # 盖伦 正在前往事发地点...
    # 2045877480
    
    • 输出结果
    <__main__.Hero object at 0x0318B100>
    <__main__.Hero object at 0x0318B0D0>
    51928864
    51928912
    泰达米尔 正在前往事发地点...
    2045877480
    盖伦 正在前往事发地点...
    2045877480
    
    • 如果是属性则直接输出其地址值,如果是方法则先执行方法在输出地址值
    • 通过一个类,可以创建多个对象,就好比通过一个模具创建多个实体一样
    • init(self)中,默认有1个参数名字为self,如果在创建对象时传递了2个实参,那么__init__(self)中出了self作为第一个形参外还需要2个形参,例如__init__(self,x,y)

    • 注意:
    • ①在类内部获取 属性 和 实例方法,通过self获取;
    • ②在类外部获取 属性 和 实例方法,通过对象名获取。
    • ③如果一个类有多个对象,每个对象的属性是各自保存的,都有各自独立的地址
    • 但是实例方法是所有对象共享的,只占用一份内存空间。类会通过self来判断是哪个对象调用了实例方法。

    七.魔法方法__str__()

    • 当使用print输出对象的时候,默认打印对象的内存地址。如果类定义了__str__(self)方法,那么就会打印从在这个方法中 return 的数据
    class Hero(object):
        """定义了一个英雄类,可以移动和攻击"""
    
        def __init__(self, name, skill, hp, atk, armor):
            """ __init__() 方法,用来做变量初始化 或 赋值 操作"""
            # 英雄名
            self.name = name  # 实例变量
            # 技能
            self.skill = skill
            # 生命值:
            self.hp = hp   # 实例变量
            # 攻击力
            self.atk = atk
            # 护甲值
            self.armor = armor
    
        def move(self):
            """实例方法"""
            print("%s 正在前往事发地点..." % self.name)
    
        def attack(self):
            """实例方法"""
            print("发出了一招强力的%s..." % self.skill)
    
        # def info(self):
        #     print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
        #     print("英雄 %s 的攻击力 :%d" % (self.name, self.atk))
        #     print("英雄 %s 的护甲值 :%d" % (self.name, self.armor))
    
    
        def __str__(self):
            """
                这个方法是一个魔法方法 (Magic Method) ,用来显示信息
                该方法需要 return 一个数据,并且只有self一个参数,当在类的外部 print(对象) 则打印这个数据
            """
            return "英雄 <%s> 数据: 生命值 %d, 攻击力 %d, 护甲值 %d" % (self.name, self.hp, self.atk, self.armor)
    
    
    taidamier = Hero("泰达米尔", "旋风斩", 2600, 450, 200)
    gailun = Hero("盖伦", "大宝剑", 4200, 260, 400)
    
    # 如果没有__str__ 则默认打印 对象在内存的地址。
    # 当类的实例化对象 拥有 __str__ 方法后,那么打印对象则打印 __str__ 的返回值。
    print(taidamier)
    print(gailun)
    
    # 查看类的文档说明,也就是类的注释
    print(Hero.__doc__)
    
    英雄 <泰达米尔> 数据: 生命值 2600, 攻击力 450, 护甲值 200
    英雄 <盖伦> 数据: 生命值 4200, 攻击力 260, 护甲值 400
    定义了一个英雄类,可以移动和攻击
    
    • ①在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法
    • ②__str__方法通常返回一个字符串,作为这个对象的描述信息

    八.魔法方法__del__()

    • 创建对象后,python解释器默认调用__init__()方法;
    • 当删除对象时,python解释器也会默认调用一个方法,这个方法为__del__()方法
    class Hero(object):
    
        # 初始化方法
        # 创建完对象后会自动被调用
        def __init__(self, name):
            print('__init__方法被调用')
            self.name = name
    
        # 当对象被删除时,会自动被调用
        def __del__(self):
            print("__del__方法被调用")
            print("%s 被 GM 干掉了..." % self.name)
    
    
    # 创建对象
    taidamier = Hero("泰达米尔")
    
    # 删除对象
    print("%d 被删除1次" % id(taidamier))
    del(taidamier)
    
    
    print("--" * 10)
    
    
    gailun = Hero("盖伦")
    gailun1 = gailun
    gailun2 = gailun
    
    print("%d 被删除1次" % id(gailun))
    del(gailun)
    
    print("%d 被删除1次" % id(gailun1))
    del(gailun1)
    
    print("%d 被删除1次" % id(gailun2))
    del(gailun2)
    
    • 运行结果
    __init__方法被调用
    54112464 被删除1次
    __del__方法被调用
    泰达米尔 被 GM 干掉了...
    --------------------
    __init__方法被调用
    54112464 被删除154112464 被删除1次
    __del__方法被调用
    盖伦 被 GM 干掉了...
    
    • 当有变量保存了一个对象的引用时,此对象的引用计数就会加1;
    • 当使用del() 删除变量指向的对象时,则会减少对象的引用计数。如果对象的引用计数不为1,那么会让这个对象的引用计数减1,当对象的引用计数为0的时候,则对象才会被真正删除(内存被回收)。

    • The best investment is in yourself
      在这里插入图片描述
    • 2020.04.03 记录辰兮的第46篇博客
    展开全文
  • 面向对象编程及其三大特性

    千次阅读 2019-06-11 11:39:23
    编程语言分为面向过程编程、函数式编程和面向对象编程。其实python就是一种面向对象编程,那么我们先了解一下它们的特点和优缺点以及它们的区别是什么。 面向过程编程:“面向过程”(Procedure Oriented)是一种以...

    编程语言分为面向过程编程、函数式编程和面向对象编程。其实python就是一种面向对象编程,那么我们先了解一下它们的特点和优缺点以及它们的区别是什么。

    面向过程编程:“面向过程”(Procedure Oriented)是一种以过程为中心的编程思想。这些都是以什么正在发生为 目标进行编程,不同于面向对象的是谁在受影响。与面向对象明显的不同就是封装、继承、类。

    面向过程编程最易被初学者接受,其往往用一长段代码来实现指定功能,开发过程的思路是将数据与函数按照执行的逻辑顺序组织在一起,数据与函数分开考虑。

    • 特性:模块化   流程化
    • 优点:性能比面向对象高,因为类调用时需要实例化,开销比较大,比较消耗资源;单片机、嵌入式开发、Linux/Unix等一般采用面向过程开发,性能是最重要的因素。
    • 缺点:没有面向对象易维护、易复用、易扩展

    函数式编程: 函数式编程也是种编程方式,它将电脑运算视为函数的计算。函数编程语言最重要的基础是λ演算(lambda calculus),而且λ演算的函数可以接受函数当作输入(参数)和输出(返回值)。

    它的主要思想是把运算过程尽量写成一系列嵌套的函数调用。

    Python 不是也不大可能会成为一种函数式编程语言,但是它支持许多有价值的函数式编程语言构建。也有些表现得像函数式编程机制但是从传统上也不能被认为是函数式编程语言的构建。

    Python内建函数 : filter()、map()、reduce()、max()、min()

    面向对象编程:面向对象是按人们认识客观世界的系统思维方式,采用基于对象(实体)的概念建立模型,模拟客观世界分析、设计、实现软件的办法。通过面向对象的理念使计算机软件系统能与现实世界中的系统一一对应。

    面向对象编程可以将数据与函数绑定到一起,进行封装,这样能够更快速的开发程序,减少了重复代码的重写过程。

    • 特性:抽象 封装 继承 多态
    • 优点:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合  的系统,使系统更加灵活、更加易于维护
    • 缺点:性能比面向过程低

    可以拿生活中的实例来理解面向过程与面向对象,例如五子棋,面向过程的设计思路就是首先分析问题的步骤:1、开始游戏,2、黑子先走,3、绘制画面,4、判断输赢,5、轮到白子,6、绘制画面,7、判断输赢,8、返回步骤2,9、输出最后结果。把上面每个步骤用不同的方法来实现。

    如果是面向对象的设计思想来解决问题。面向对象的设计则是从另外的思路来解决问题。整个五子棋可以分为1、黑白双方,这两方的行为是一模一样的,2、棋盘系统,负责绘制画面,3、规则系统,负责判定诸如犯规、输赢等。第一类对象(玩家对象)负责接受用户输入,并告知第二类对象(棋盘对象)棋子布局的变化,棋盘对象接收到了棋子的变化就要负责在屏幕上面显示出这种变化,同时利用第三类对象(规则系统)来对棋局进行判定。

    可以明显地看出,面向对象是以功能来划分问题,而不是步骤。同样是绘制棋局,这样的行为在面向过程的设计中分散在了多个步骤中,很可能出现不同的绘制版本,因为通常设计人员会考虑到实际情况进行各种各样的简化。而面向对象的设计中,绘图只可能在棋盘对象中出现,从而保证了绘图的统一。 


     面向对象编程三大特性

    在看面向对象编程三大特性之前,先了解一下对象和类的区别。

    对象和类 

    类(Class)是现实或思维世界中的实体在计算机中的反映,它将数据以及这些数据上的操作封装在一起。类实际上是创建实例的模板。

    对象(Object)是具有类类型的变量。类和对象是面向对象编程技术中的最基本的概念。 而对象就是一个一个具体的实例。

     定义类的方法: 

    class 类():  

              pass

    那么如何将类转换成对象呢?

    实例化是指在面向对象的编程中,把用类创建对象的过程称为实例化。是将一个抽象的概念类,具体到该类实物的过程。实例化过程中一般由类名 对象名 = 类名(参数1,参数2...参数n)构成。

    定义类之后一般会用到构造方法__init__与其他普通方法不同的地方在于,当一个对象被创建后,会立即调用构造方法(也称为魔术方法)。自动执行构造方法里面的内容。

     1.封装特性

    封装,顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容。 所以,在使用面向对象的封装特性时,需要:

    1. 将内容封装到某处
    2. 从某处调用被封装的内容,调用方法如下:
    • 通过对象直接调用被封装的内容: 对象.属性名
    • 通过self间接调用被封装的内容:  self.属性名
    • 通过self间接调用被封装的内容:    self.方法名()

    对于面向对象的封装来说,其实就是使用构造方法将内容封装到 对象 中,然后通过 对象直接或者self间接获取被封装的内容。 

    具体例子如下:

    # 1). 类的定义
    class People:
        # 构造方法(魔术方法): 当创建对象时会自动调用并执行;
        # self实质上是实例化出来的对象, e.g: xiaoming, xiaohong;
        def __init__(self, name, age, gender):
            # print("正在创建对象")
            # print(self) # 实质上是一个对象
            # 将创建对象的属性(name, age, gender)封装到self(就是实例化的对象)变量里面;
            # 在类里面定义的变量: 属性
            self.name = name
            self.age = age
            self.gender = gender
        # 在类里面定义的函数: 方法
        def eat(self):
            print('%s eating......' %(self.name))
    
        def sleep(self):
            # 获取对象self封装的属性(name, age, gender)
            print('%s sleep.......' %(self.name))
    
    # 2). 实例化: 通过类实现对象的创建
    xiaoming = People("小明", 20, '男')
    # 将对象self/xiaoming封装的属性(name, age, gender)从里面拿出来;
    print(xiaoming.name)
    xiaoming.eat()
    xiaoming.sleep()
    
    xiaohong = People("小红", 20, '女')
    print(xiaohong.name)
    xiaohong.eat()
    xiaohong.sleep()

     2.继承特性

     1)继承

    继承描述的是事物之间的所属关系,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类、扩展类(Subclass),而被继承的class称为基类、父类或超类(Baseclass、Superclass)。

    问题一:如何实现继承呢?         

    子类在继承的时候,在定义类时,小括号()中为父类的名字,例如: class son(father):   这里father就是son的父类。    

    问题二:继承的工作机制是什么?             

    父类的属性、方法,会被继承给子类。 举例如下:如果子类没有定义__init__方法,父类有,那么在子类继承父类的时候这个方法就被继承了,所以只要创建对象,就默认执行了那个继承过来的__init__方法。

    重写父类方法:就是在子类中,有一个和父类相同名字的方法,那么在子类中的方法就会覆盖掉父类中同名的方法,就实现了对父类方法的重写。

    调用父类的方法:

    1. 在子类中,直接利用  父类名.父类的方法名() 
    2. super()方法: python2.2+的功能,格式为: super(子类名称, self).父类的方法名() (建议用此方法)

    2)多继承 

     多继承,即子类有多个父类,并且具有它们的特征。

    新式类与经典类的区别:

    在Python 2及以前的版本中,由任意内置类型派生出的类,都属于“新式类”,都会获得所有“新式类”的特性;反之,即不由任意内置类型派生出的类,则称之为“经典类”。

    新式类:

    class 类名(object):

            pass

    经典类:

    class 类名:

           pass

    “新式类”和“经典类”的区分在Python 3之后就已经不存在,在Python 3.x之后的版本,因为所有的类都派生自内置类型object(即使没有显示的继承object类型),即所有的类都是“新式类”。 

    它们两个最明显的区别在于继承搜索的顺序不同,即:    

    经典类多继承搜索顺序(深度优先算法):先深入继承树左侧查找,然后再返回,开始查找右侧。    

    新式类多继承搜索顺序(广度优先算法):先在水平方向查找,然后再向上查找。

    图示如下:

     

    具体例子如下:

    # python2:
        # 经典类: 	class Father:
        # 新式类:   class Father(object):
    # python3:
    #       所有的都是新式类
    
    # 新式类:  广度优先
    # 经典类:  深度优先
    class D:
    	a = 'd'
    
    class B(D):
    	pass
    
    class C(D):
    	a = 'c'
    
    class A(B, C):
    	pass
    obj = A()
    print(obj.a)

    运行结果是 c,由此可见为广度优先搜索的结果。

    3)私有属性与私有方法

    默认情况下,属性在 Python 中都是“public”, 大多数 OO (面向对象)语言提供“访问控制符”来限定成员函数的访问。 

    在 Python 中,实例的变量名如果以 __ (双下划线)开头,就变成了一个私有变量/属性(private),实例的函数名如果以 __ 开头,就变成了一个私有函数/方法(private)只有内部可以访问,外部不能访问。

    那么私有属性一定不能从外部访问吗?

    python2版本不能直接访问 __属性名,是因为 Python 解释器对外把  __属性名 改成了  _类名__属性名 ,所以,仍然可以通过 _类名__属性名  来访问 __属性名 。 但是不同版本的 Python 解释器可能会把 __属性名  改成不同的变量名,因此不建议用此类方法访问私有属性。 

    私有属性和方法的优势:

    1. 确保了外部代码不能随意修改对象内部的状态,这样通过访问限制的保护,代码更加健壮。      
    2. 如果有要允许外部代码修改属性怎么办?可以给类增加专门设置属性方法。 为什么大费周折?因为在方法中,可以对参数做检查,避免传入无效的参数。

    具体实例如下:

    class Student(object):
        __country = 'china'
        def __init__(self, name, age, score):
            self.name = name
            # 年龄和分数是私有属性
            self.__age = age
            self.__score = score
    
        # 私有方法, 只能在类内部执行;
        def __modify_score(self, scores):
            self.__score = scores
            print(self.__score)
    
        def set_age(self, age):
            if 0<age <150:
                self.__age = age
                print("当前年龄:", self.__age)
            else:
                raise  Exception("年龄错误")
    
        def set_score(self, scores):
            if len(scores) == 3:
                self.__score = scores
            else:
                raise Exception("成绩异常")
    class MathStudent(Student):
        pass
    
    student = Student("Tom", 10, [100, 100, 100])
    # 在类的外部是不能直接访问的;
    print(student.name)
    
    student.set_age(15)
    # Python 解释器对外把  __属性名 改成了  _类名__属性名
    # print(student._Student__age)

    3.多态特性 

    多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多态。通俗来说: 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

    多态的好处就是,当我们需要传入更多的子类,只需要继承父类就可以了,而方法既可以直接不重写(即使用父类的),也可以重写一个特有的。这就是多态的意思。调用方只管调用,不管细节,而当我们新增一种的子类时,只要确保新方法编写正确,而不用管原来的代码。这就是著名的“开放封闭”原则: 

    • 对扩展开放(Open for extension):允许子类重写方法函数    
    • 对修改封闭(Closed for modification):不重写,直接继承父类方法函数

     

    展开全文
  • 面向对象编程思想

    千次阅读 2018-10-11 07:35:59
    Java面向对象编程思想Java对象什么是对象如何创建对象对象的生命周期继承什么是继承继承语法向上转型继承与初始化多态什么是多态产生正确的行为功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入...
  • 如果要用一句话来概括面向对象编程,我认为下面的说法是相当精准的。 面向对象编程:把一组数据和处理数据的方法组成对象,把行为相同的对象归纳为类,通过封装隐藏对象的内部细节,通过继承实现类的特化和泛化,...
  • 基于python下的面向对象编程

    千次阅读 2018-07-23 09:53:38
    先来了解面向对象和面向过程是什么? 面向过程就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现, 使用的时候一个一个依次调用就可以了;面向对象是把构成问题事务分解成各个对象, 建立对象...
  • 面向对象编程,再见!

    千次阅读 多人点赞 2018-10-07 17:30:00
    作为程序员,你是使用函数式编程还是面向对象编程方式?在本文中,拥有 10 多年软件开发经验的作者从面向对象编程的三大特性——继承、封装、多态三大角度提出了自己的疑问,并深刻表示是时候和面向对象编程说再见了...
  • 何为面向对象编程

    2020-11-24 16:27:42
    何为面向对象编程 面向对象编程简介 面向对象编程(Object-oriented Programming,缩写:OOP)是软件工程中一种具有对象概念的编程范式(Programming Paradigm),同时也是一种程序开发的抽象方针,与之对应的编程范式...
  • 面向对象编程,再见!

    千次阅读 2018-12-25 12:32:17
    作为程序员,你是使用函数式编程还是面向对象编程方式?在本文中,拥有 10 多年软件开发经验的作者从面向对象编程的三大特性——继承、封装、多态三大角度提出了自己的疑问,并深...
  • 面向对象编程基本概念

    千次阅读 2018-04-18 15:41:53
    面向对象编程(OOP)为软件社区引入了一场革命,以帮助解决这些问题。 OOP专注于模块化,改变容忍度,代码重用,易于理解和分布式开发。今天大多数项目都使用面向对象的概念。由于C ++引入了OOP,因此用户体验已经...
  • C 语言实现面向对象编程

    万次阅读 多人点赞 2018-08-14 18:36:38
    面向对象编程(OOP)并不是一种特定的语言或者工具,它只是一种设计方法、设计思想。它表现出来的三个最基本的特性就是封装、继承与多态。很多面向对象的编程语言已经包含这三个特性了,例如 Smalltalk、C++、Java。...
  • 面向对象编程

    千次阅读 2019-06-11 11:30:21
    面向对象的三大特性: 封装 , 继承 和多态 一. 面向过程编程 1.定义: 是一种以过程为中心的编程思想。这些都是以什么正在发生为目标进行编程,不同于面向对象的是谁在受影响。于面向对象明显 的不同就是封装,...
  • 面向对象编程是什么意思

    千次阅读 2017-03-20 16:33:50
    它是一种编程风格, 就是把一切东西看成一个个对象,比如人,车,面包,等等, 然后把这些对象拥有的属性变量,比如年龄,民族,工作地点,变质期,寿命, 还有操作这些属性变量...这就是的面向对象的特点!!!...
  • C++面向对象程序设计 面向对象编程

    千次阅读 2018-09-12 22:39:50
    1.1 面向过程的编程风格与面向对象编程风格 C语言是面向过程语言,也称为命令型语言,面向过程通常采用自顶向下设计,问题复杂时不断运用自顶向下设计(即函数分解法)直到容易处理。自顶向下设计优点是直观有...
  • Java 面向对象编程.pdf

    千次下载 热门讨论 2012-12-24 17:41:29
    《Java 面向对象编程》内容由浅入深,紧密结合实际,利用大量典型实例,详细讲解Java面向对象的编程思想、编程语法和设计模式,介绍常见Java类库的用法,总结优化Java编程的各种宝贵经验,深入阐述Java虚拟机执行...
  • 由谭浩强编著的《C++面向对象程序设计》(清华大学出版社出版)一书中各章的例题程序,以方便教师进行教学,也便于读者上机运行这些程序以及在此基础上修改和调试程序。 程序按章设立文件夹(子目录),如文件夹c6中包含...
  • Python中的面向对象程序设计

    千次阅读 2019-05-07 23:08:31
    面向对象程序设计是在面向过程程序设计的基础上发展而来的,它比面向编程具有更强的灵活性和扩展性,本次学习需要了解以下内容; ①了解什么是面向对象; ②掌握如何定义和使用类; ③掌握如何创建类的属性; ④掌握...
  • C++面向对象程序设计50道编程题(第01题)

    万次阅读 多人点赞 2018-11-27 21:43:46
    C++面向对象程序设计50道编程题(第01题) 摘要:C++程序设计实习是为学生提供了一个既动手又动脑,独立实践的机会,将课本上的理论知识和实际有机的结合起来,锻炼学生的分析问题和解决问题的能力,提高学生运用所...
  • 在计算机科学中,对象(英语:object),台湾译作物件,是一个存储器地址,...是面向对象(Object Oriented)中的术语,既表示客观世界问题空间(Namespace)中的某个具体的事物,又表示软件系统解空间中的基本元素。

空空如也

1 2 3 4 5 ... 20
收藏数 714,472
精华内容 285,788
关键字:

面向对象编程