精华内容
下载资源
问答
  • 如果类中有成员变量并对成员变量有初始化操作,那么创建构造函数时会先调用构造函数,然后按顺序对成员变量赋值,例如如下代码创建Main对象时 会首先跳到public Main()那一行,然后跳转到 int price = 80;然后按...

    构造函数

    和类名同名,没有返回类型,如果类中没有创建构造函数,会缺省的创建一个构造函数,例如一个名为Main的类其缺省的构造函数为

    public class Main {
    	//缺省构造函数
    	public Main() 
    	{
    		
    	}
    }
    

    如果类中有成员变量并对成员变量有初始化操作,那么创建构造函数时会先调用构造函数,然后按顺序对成员变量赋值,例如如下代码创建Main对象时
    会首先跳到public Main()那一行,然后跳转到 int price = 80;然后按顺序执行后面的成员变量赋值语句,最后回到构造函数,将total赋值为零。最终,total的值为零

        public class Main {
        int price = 80;
        int balance = f();
    	int total = 90;
    	public Main() 
    	{
    		total = 0;
    	}
    	int f() 
    	{
    		return 10;
    	}
    	public static void main(String[] args) {
    		Main main = new Main();
    	}
    }
    
    展开全文
  • 创建派生类对象构造函数执行顺序() 正确答案: A A 基类构造函数,派生类对象成员构造函数,派生类本身的构造函数 B 派生类本身的构造函数,基类构造函数对象成员构造函数 C 基类构造函数,派生类...

    在创建派生类对象,构造函数的执行顺序()
    正确答案: A

    • A 基类构造函数,派生类对象成员构造函数,派生类本身的构造函数

    • B 派生类本身的构造函数,基类构造函数,对象成员构造函数

    • C 基类构造函数,派生类本身的构造函数,派生类对象成员构造函数

    • D 对象成员构造函数,基类构造函数,派生类本身的构造函数

    对象创建时代码的加载顺序为:静态代码 --> 非静态代码 --> 构造方法。

    若继承了父类,则加载顺序为:父类的静态的代码 --> 子类的静态的代码 --> 父类内部非静态代码 --> 父类的构造方法 --> 子类的非静态代码 --> 子类的构造方法。

    其中,静态代码包括(静态方法,静态变量,静态代码块等),非静态代码即(成员方法,成员变量,成员代码块等),同一种代码,写在上面的先加载

    
    public class ExtendsTest {
    
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		C c = new D();
    	}
    
    }
    
    class C {
    	static {
    		System.out.println("C 基类静态域 ");
    	}
    	{
    		System.out.println("C 基类对象成员构造函数");
    	}
    
    	public C() {
    		System.out.println("C 基类本身的构造函数");
    	}
    }
    
    class D extends C {
    	static {
    		System.out.println("D 派生类静态域");
    	}
    	{
    		System.out.println("D 派生类对象成员构造函数");
    	}
    
    	public D() {
    		System.out.println("D 派生类本身的构造函数");
    	}
    }
    
    

    在这里插入图片描述

    展开全文
  • JavaScript构造函数及原型对象 使用Object或对象字面量创建对象 工厂模式创建对象 构造函数模式创建对象 原型模式创建对象 构造与原型混合模式创建对象

    JavaScript中没有类的概念,所以其在对象创建方面与面向对象语言有所不同。

     JS中对象可以定义为”无序属性的集合”。其属性可以包含基本值,对象以及函数。对象实质上就是一组没有特定顺序的值,对象中每个属性、方法都有一个名字,每个名字都映射到了一个值,因此我们可以将对象想象称为一个散列表。

    JS是一种基于对象的语言,对象的概念在JS体系中十分的重要,因此有必要清楚地了解一下JS中对象创建的常用方法及各自的局限性。


    使用Object或对象字面量创建对象

    在说工厂模式创建对象之前,我们不妨回顾一下JS中最基本的创建对象的方法,比如说我想创建一个student对象怎么办?最简单地,new一个Object:

    var student = new Object();
    student.name = "easy";
    student.age = "20";
    

    这样,一个student对象就创建完毕,拥有2个属性name以及age,分别赋值为"easy"20

    如果你嫌这种方法有一种封装性不良的感觉,我们也可以使用对象字面量的方式来创建student对象:

    var sutdent = {
      name : "easy",
      age : 20
    };
    

    这样看起来似乎就完美了。但是马上我们就会发现一个十分尖锐的问题:当我们要创建同类的student1,student2,…,studentn时,我们不得不将以上的代码重复n次。

    var sutdent1 = {
      name : "easy1",
      age : 20
    };
    
    var sutdent2 = {
      name : "easy2",
      age : 20
    };
    
    ...
    
    var sutdentn = {
      name : "easyn",
      age : 20
    };
    

    能不能像工厂车间那样,有一个车床就不断生产出对象呢?我们看”工厂模式”。

    工厂模式创建对象

    JS中没有类的概念,那么我们不妨就使用一种函数将以上对象创建过程封装起来以便于重复调用,同时可以给出特定接口来初始化对象:

    function createStudent(name, age) {
      var obj = new Object();
      obj.name = name;
      obj.age = age;
      return obj;
    }
    
    var student1 = createStudent("easy1", 20);
    var student2 = createStudent("easy2", 20);
    ...
    var studentn = createStudent("easyn", 20);
    

    这样一来我们就可以通过createStudent函数源源不断地”生产”对象了。看起来已经高枕无忧了,但贪婪的人类总有不满足于现状的天性:我们不仅希望”产品”的生产可以像工厂车间一般源源不断,我们还想知道生产的产品究竟是哪一种类型的。

    比如说,我们同时又定义了”生产”水果对象的createFruit()函数:

    function createFruit(name, color) {
      var obj = new Object();
      obj.name = name;
      obj.color = color;
      return obj;
    }
    
    var v1 = createStudent("easy1", 20);
    var v2 = createFruit("apple", "green");
    

    对于以上代码创建的对象v1、v2,我们用instanceof操作符去检测,他们统统都是Object类型。我们的当然不满足于此,我们希望v1是Student类型的,而v2是Fruit类型的。为了实现这个目标,我们可以用自定义构造函数的方法来创建对象。

    构造函数模式创建对象

    在上面创建Object这样的原生对象的时候,我们就使用过其构造函数:

    var obj = new Object();
    

    在创建原生数组Array类型对象时也使用过其构造函数:

    var arr = new Array(10);  //构造一个初始长度为10的数组对象
    

    在进行自定义构造函数创建对象之前,我们首先了解一下构造函数普通函数有什么区别。

    其一,实际上并不存在创建构造函数的特殊语法,其与普通函数唯一的区别在于调用方法。对于任意函数,使用new操作符调用,那么它就是构造函数;不使用new操作符调用,那么它就是普通函数。

    其二,按照惯例,我们约定构造函数名以大写字母开头,普通函数以小写字母开头,这样有利于显性区分二者。例如上面的new Array(),new Object()。

    其三,使用new操作符调用构造函数时,会经历(1)创建一个新对象;(2)将构造函数作用域赋给新对象(使this指向该新对象);(3)执行构造函数代码;(4)返回新对象;4个阶段。

    了解了构造函数普通函数的区别之后,我们使用构造函数将工厂模式的函数重写,并添加一个方法属性:

    function Student(name, age) {
      this.name = name;
      this.age = age;
      this.alertName = function(){
        alert(this.name)
      };
    }
    
    function Fruit(name, color) {
      this.name = name;
      this.color = color;
      this.alertName = function(){
        alert(this.name)
      };
    }
    

    这样我们再分别创建Student和Fruit的对象:

    var v1 = new Student("easy", 20);
    var v2 = new Fruit("apple", "green");
    

    这时我们再来用instanceof操作符来检测以上对象类型就可以区分出Student以及Fruit了:

    alert(v1 instanceof Student);  //true
    alert(v2 instanceof Student);  //false
    alert(v1 instanceof Fruit);  //false
    alert(v2 instanceof Fruit);  //true
    
    alert(v1 instanceof Object);  //true 任何对象均继承自Object
    alert(v2 instanceof Object);  //true 任何对象均继承自Object
    

    这样我们就解决了工厂模式无法区分对象类型的尴尬。那么使用构造方法来创建对象是否已经完美了呢?

    我们知道在JS中,函数是对象。那么,当我们实例化不止一个Student对象的时候:

    var v1 = new Student("easy1", 20);
    var v2 = new Student("easy2", 20);
    ...
    var vn = new Student("easyn", 20);
    

    其中共同的alertName()函数也被实例化了n次,我们可以用以下方法来检测不同的Student对象并不共用alertName()函数:

    alert(v1.alertName == v2.alertName);  //flase
    

    这无疑是一种内存的浪费。我们知道,this对象是在运行时基于函数的执行环境进行绑定的。在全局函数中,this对象等同于window;在对象方法中,this指向该对象。在上面的构造函数中:

    this.alertName = function(){
        alert(this.name)
      };
    

    我们在创建对象(执行alertName函数之前)时,就将alertName()函数绑定在了该对象上。我们完全可以在执行该函数的时候再这样做,办法是将对象方法移到构造函数外部:

    function Student(name, age) {
      this.name = name;
      this.age = age;
      this.alertName = alertName;
    }
    
    function alertName() {
      alert(this.name);
    }
    
    var stu1 = new Student("easy1", 20);
    var stu2 = new Student("easy2", 20);
    

    在调用stu1.alert()时,this对象才被绑定到stu1上。

    我们通过将alertName()函数定义为全局函数,这样对象中的alertName属性则被设置为指向该全局函数的指针。由此stu1和stu2共享了该全局函数,解决了内存浪费的问题。

    但是,通过全局函数的方式解决对象内部共享的问题,终究不像一个好的解决方法。如果这样定义的全局函数多了,我们想要将自定义对象封装的初衷便几乎无法实现了。更好的方案是通过原型对象模式来解决。

    原型模式创建对象

    函数的原型对象

    在了解如何使用原型模式创建对象之前,有必要先搞清楚什么是原型对象。

    我们创建的每一个函数都有一个prototype属性,该属性是一个指针,该指针指向了一个对象。对于我们创建的构造函数,该对象中包含可以由所有实例共享的属性和方法。如下如所示:

    原型对象

    在默认情况下,所有原型对象会自动包含一个constructor属性,该属性也是一个指针,指向prototype所在的函数:

    原型对象-constructor

    对象实例和原型对象的关联

    在调用构造函数创建新的实例时,该实例的内部会自动包含一个[[Prototype]]指针属性,该指针指便指向构造函数的原型对象。注意,这个指针关联的是实例与构造函数的原型对象而不是实例与构造函数

    实例与原型对象

    使用原型模型创建对象

    直接在原型对象中添加属性和方法

    了解了原型对象之后,我们便可以通过在构造函数原型对象中添加属性和方法来实现对象间数据的共享了。例如:

    function Student() {
    }
    
    Student.prototype.name = "easy";
    Student.prototype.age = 20;
    Student.prototype.alertName = function(){
                                    alert(this.name);
                                  };
    
    var stu1 = new Student();
    var stu2 = new Student();
    
    stu1.alertName();  //easy
    stu2.alertName();  //easy
    
    alert(stu1.alertName == stu2.alertName);  //true 二者共享同一函数
    

    以上代码,我们在Student的protptype对象中添加了name、age属性以及alertName()方法。但创建的stu1和stu2中并不包含name、age属性以及alertName()方法,而只包含一个[[prototype]]指针属性。当我们调用stu1.namestu1.alertName()时,是如何找到对应的属性和方法的呢?

    当我们需要读取对象的某个属性时,都会执行一次搜索。首先在该对象中查找该属性,若找到,返回该属性值;否则,到[[prototype]]指向的原型对象中继续查找。

    由此我们也可以看出另外一层意思:如果对象实例中包含和原型对象中同名的属性或方法,则对象实例中的该同名属性或方法会屏蔽原型对象中的同名属性或方法。原因就是“首先在该对象中查找该属性,若找到,返回该属性值;”

    拥有同名实例属性或方法的示意图:

    上图中,我们在访问stu1.name是会得到”EasySir”:

    alert(stu1.name);  //EasySir
    

    通过对象字面量重写原型对象

    很多时候,我们为了书写的方便以及直观上的”封装性”,我们往往采用对象字面量直接重写整个原型对象:

    function Student() {
    }
    
    Student.prototype = {
      constructor : Student,
      name : "easy",
      age : 20,
      alertName : function() {
        alert(this.name);
      }
    };
    

    要特别注意,我们这里相当于用对象字面量重新创建了一个Object对象,然后使Student的prototype指针指向该对象。该对象在创建的过程中,自动获得了新的constructor属性,该属性指向Object的构造函数。因此,我们在以上代码中,增加了constructor : Student使其重新指回Student构造函数。

    原型模型创建对象的局限性

    原型模型在对象实例共享数据方面给我们带来了很大的便利,但通常情况下不同的实例会希望拥有属于自己单独的属性。我们将构造函数模型和原型模型结合使用即可兼得数据共享和”不共享”。

    构造与原型混合模式创建对象

    我们结合原型模式在共享方法属性以及构造函数模式在实例方法属性方面的优势,使用以下的方法创建对象:

    //我们希望每个stu拥有属于自己的name和age属性
    function Student(name, age) {
      this.name = name;
      this.age = age;
    }
    
    //所有的stu应该共享一个alertName()方法
    Student.prototype = {
      constructor : Student,
      alertName : function() {
                    alert(this.name);
                  }
    }
    
    var stu1 = new Student("Jim", 20);
    var stu2 = new Student("Tom", 21);
    
    stu1.alertName();  //Jim  实例属性
    stu2.alertName();  //Tom  实例属性
    
    alert(stu1.alertName == stu2.alertName);  //true  共享函数
    

    以上,在构造函数中定义实例属性,在原型中定义共享属性的模式,是目前使用最广泛的方式。通常情况下,我们都会默认使用这种方式来定义引用类型变量。

    展开全文
  • 新手踩坑,python构造函数创建对象时,没有自动执行,object has no attribute 刚开始学python,照着书敲,就离谱,一直在报错object has no attribute,后来发现:在创建对象后,构造函数没有执行。 构造函数为...

    新手踩坑,python构造函数在创建对象时,没有自动执行,object has no attribute

    刚开始学python,照着书敲,就离谱,一直在报错object has no attribute,后来发现:在创建对象后,构造函数没有执行。
    报错内容
    构造函数为什么没有执行,看颜色,我是手敲的,而不是选中
    在这里插入图片描述
    如上图,手敲的话就是黑色,会认为是自定义函数,而选中的为蓝色的,是系统的函数,比如这个构造方法。用这种选中的方法就好了。
    在这里插入图片描述
    小白菜鸡勿喷,超级感恩。

    展开全文
  • #include "stdafx.h" ...// 没有显示声明构造函数,编译器会调用默认的构造函数 class Test1 { public: int i; string str; }; // 显示声明了构造函数 class Test2 { public: Test2(); Test2(int i, st
  • 构造函数创建对象

    2019-07-27 16:02:25
    //构造函数创建对象 function Box(name,age){ //创建一个对象 this.name = name; //添加一个属性 this.age = age; this.run = function(){ return this.name + this.age + '运行中...'; }; ...
  • 像Object 和 Array这样的原生构造函数,在运行时自动出现在执行环境中。此外,也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。例如,可以使用构造函数模式将前面的例子重写如下。 function ...
  • C#构造函数-创建对象

    千次阅读 2010-11-22 10:57:00
    创建对象时,必须调用构造函数,如果没有定义构造函数,系统会提供一个默认的构造函数。 在访问一个类的时候,系统将最先执行构造函数中的语句,任何构造函数执行都隐式的调用了系统提供的默认构造函数base()...
  • python 类 构造函数 Python构造函数创建对象 (Python Constructors to create a Class Object) In the last tutorial, we learned how to create a class, its instance and how to access class members...
  • 本文主要说明对象创建时构造函数执行顺序,对象成员的初始化顺序;对象销毁析构函数的执行顺序,对象成员的销毁顺序。    “对象的构造从类层次的最根处开始,在每一层中,首先调用基类的构造函数,然后调用...
  •  –调用构造函数的主要目的是初始化对象 •一个对象创建过程:  –分配内存空间  –初始化成员变量,如果成员是对象,构造他  –调用构造函数 •默认的空参构造函数 构造函数的使用 •构造函数重载
  • 2.若没有提供任何构造函数,那么c++提供自动提供一个默认的构造函数,该默认构造函数是一个没有参数的构造函数,它仅仅负责创建对象而不做任何赋值操作。  3.只要类中提供了任意一个构造函数,那么
  • 通过一般创建对象的方法----到函数创建对象----构造函数创建对象,一步步学会使用构造函数创建对象
  • 新手小白学JAVA 面向对象2 构造函数 构造代码块 this

    万次阅读 多人点赞 2021-05-10 08:34:24
    当类创建对象(实例化),就会自动调用构造方法 构造方法与普通方法一样也可以重载. 1.2 形式 与类同名,且没有返回值类型,可以含参也可以不含参 1.3 练习:构造方法创建对象/构造方法赋值 创建包: cn.tedu.oop 创建...
  • 使用Oject构造函数或者对象的字面量创建单个对象的时候会有大量的重复代码。 工厂模式 是一种很常见的设计模式,就是将创建对象的过程进行了一定的抽象。在 JavaScript中无法创建类,所以我们可以用函数来封装...
  • java不通过构造函数创建对象(Unsafe)

    万次阅读 多人点赞 2020-05-31 17:02:16
    java中不通过构造函数创建对象(也有说不创建对象直接执行成员方法) 这里就不和你们扯什么通过 反序列化、clone等方法了 个人觉得都是在胡扯。 如何不执行构造函数创建对象? 先来带大家认识一个类 sun.misc.Unsafe...
  • #include <iostream> using namespace std; class Line { public: void setLength( double len ); double getLength( void ); Line(int i); // 这是构造函数声明 ~Line(); // 这是析构函数...
  • 类与对象-构造函数

    2016-10-01 22:53:35
    1.构造函数的作用对象的数据成员一般在构造函数中初始化,构造函数可以保证对象在创建后其数据成员都已经被初始化,构造函数创建对象是被自动调用,不能指定其返回类型。2.构造函数执行时机 对象被声明或创建...
  • 1、c++提供了构造函数来处理对象的初始化,他是一种特殊的成员函数,不需要用户来调用,而是在建立对象时自动执行。2、有时候我们希望不同的对象需要赋予不同的值,这是需要使用带参数的构造函数。函数首部的一般...
  • JS原型+构造函数创建对象   JavaScript对象的创建方式 在JavaScript中,创建对象的方式包括两种:对象字面量和使用new表达式。对象字面量是一种灵活方便的书写方式,例如: ? 1 ...
  • 虽然Object构造函数或对象字面量都可以创建单个对象,但是这些方式有个明显的缺点:使用同一个接口创建很多对象,会产生大量重复的代码。为了解决这个问题,就可以使用工厂模式来创建对象。1、工厂模式 在...
  • 使用无参构造函数创建对象时,不应该在对象名后面加上括号。  例如:  class CText  {  public:  CText(){}  CText(int a, int b, int c)  {  m_nA = a;
  • 面向对象 之封装、构造函数

    千次阅读 2013-07-24 09:44:22
    构造函数 1、面向对象概念 1.1如何理解面向对象 a)  面向对象是相对面向过程而言,面向对象和面向过程都是一种思想。 b)  面向过程强调的是功能行为。 c)  面向对象将功能封装进对象,强调具备了功能
  • 或者按两次ctrl+shift+L2、在类内,按alt+/,弹出窗口,可以创建构造函数。用alt+shift+s,然后o,c的方式都不行。 3、ctrl+shift+t,查找定位某个类 4、try catch 3(转)搜索整理MyEclipse 快捷键 搜索...
  • 2静态构造函数,不能访问实例成员,只能用来初始化一些静态字段或者属性,仅在第一次调用类的任何成员时自动执行,不带访问修饰符,不带任何参数,每个类只能有一个静态构造函数,但可以同时还有一个无参实例构造...
  • 此部分提取自 C++ Primer 基础部分学习笔记 默认构造函数: 通常无参数或所有的参数都有缺省值, 并且一个类中只能有...当创建对象时不提供参数将调用默认构造函数 重载构造函数: 最为常见的构造函数, 根据不同类...
  • C++的构造函数和默认构造函数详解

    万次阅读 多人点赞 2019-04-07 15:19:45
    C++的构造函数和默认构造函数 ...默认构造函数是未提供显式初始值用来构建对象构造函数。 其实这个定义并没有告诉我们什么,真正想要搞懂还是要看代码,从代码的区别来体会他们两个之间的差异。 class ...
  • new在执行构造函数时 ①在内存中创建一个新对象 ②让this指向这个新对象执行构造函数里的代码,给这个新对象添加属性和方法 ④返回这个新对象(所以构造函数里面不需要return) ...
  • 第一个问题:构造函数能被继承? 构造函数是不能被继承的。... 每次调用子类的时候都会“自动运行”它父类的构造函数,如果真的需要子类构造函数特殊的形式,子类直接修改或重载自己的构造函数就好了。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 360,730
精华内容 144,292
关键字:

创建对象时自动执行构造函数