.JAVA的构造方法-创新网络

本文深入解析Java构造方法,包括构造方法的返回值、静态误解以及在构造方法中调用被子类重写的方法时的多态现象。详细解释构造方法的作用、构造方法与new指令的关系,以及构造方法如何初始化对象并引发多态行为。
关于java的构造方法有几个简单的问题:
  1.构造方法有返回值吗?
  没有。构造方法没有任何返回类型,也不允许是void。比如:
  public class Test {
  //这不是构造函数!
  public void Test() {
  System.out.println("void Test()");
  }
  public static void main(String[] args) {
  Test test = new Test();
  test.Test();
  }
  }
  这里我们定义了一个返回类型为void的Test()方法,有了返回类型void,它就不是构造方法了。
  Test test = new Test();
  有人用上面的表达式来说明构造方法返回对象引用,这是明显错误的。new关键字有两个作用。一是分配内存,
  创建对象。二是调用构造方法,完成对象的初始化工作。完成这两部之后,才算创建了一个完整的Java对象。我们可以用Test test = new Test();的反编译代码来说明这个问题:
  0: new #5; //class Test
  3: dup
  4: invokespecial #6; //Method "":()V
  7: astore_1
  一个对象创建并赋值表达式被编译成四条指令。第一行的new指令负责根据参数分配内存并创建Test对象,然后将新创建对象的引用置于栈顶。dup指令复制栈顶的内容,记住,此时栈最顶端的两个单元都是新创建对象的引用。下面是调用初始化方法,该方法是由构造方法编译而来,栈顶的引用作为此方法的参数消耗了一个。通过调用初始化方法完成对象的创建过程。这里注意一下初始化方法Method "":()V,它是void类型的。最后的astore_1指令将栈顶的对象引用赋给局部变量(前面说了,dup之后栈顶两个引用,一个给初始化方法吃掉了,一个留给astore_1操作用),也就是执行赋值操作。
  因此,得到的引用是new指令的结果,不是构造方法的返回值。
  有一点需要注意:new指令创建对象,同时使对象的各个字段得到其默认值,比如整数为0,浮点数为0.0,引用为null,boolean为false等。这一点我们在第三条继续说明。
  通过上面说明,我们明确了构造方法的职能(初始化new指令创建的对象,得到一个状态合法的对象,完成对象的创建过程)。任何类都有构造方法,但是new指令只能创建非抽象类的对象。理解了这一点,也就不要再问"抽象类也有构造方法,为什么不能创建对象"之类的问题了。
  2.构造方法是静态的?
  错误。
  这是《Thinking In Java》中的一个观点。书里有一段:
  Even though it doesn't explicitly use the static keyword, the constructor is actually a static method. So the first time an object of type Dog is created, or the first time a static method or static field of class Dog is accessed, the Java interpreter must locate Dog.class,which it does by searching through the classpath.
  《java编程思想》第四版96页:
  总结一下对象的创建过程,假设有个名为Dog的类:
  1.即使没有显示地使用static关键字,构造器实际上也是静态方法。因此,当首次创建类型为Dog的对象时(构造器可以看成是静态方法),或者Dog类的静态方法/静态域首次被访问时,Java解释器必须查找类路径,以定位Dog.class文件。这里我并没有看出作者为什么说构造器实际上是静态方法。但是我们知道,静态方法是不能使用this的。因此,"构造器实际上也是静态方法"这点很好否定。看下面例子:
  public class Test {
  public Test() {
  this.test2();
  }
  public static void test(){
  this.test2();
  }
  public static void test2(){
  }
  }
  test方法编译错误,因为静态方法中不能使用非静态的this,而构造方法使用this是没有问题的。
  如果有C++经验的话,可以类比一下。C++里的new操作符有两个作用,调用operator new()来分配内存,然后调用构造函数来完成初始化。而这里的operator new()是隐式静态的。参考《C++程序设计语言(特别版)》中文版的374页:
  比如这个例子:
  class Employee{
  //...
  public:
  //....
  void* operator new(size_t);
  void operator delete(void* ,size_t);
  }
  成员operator new()和operator delete()默认为static成员,因为它们没有this指针,也不会修改任何对象。它们将提供一些存储,供构造函数去初始化,而后由析构函数去清理。类比可知,静态的是负责分配内存的工具,而不是构造函数。
  3父类的构造方法中调用被子类重写的方法有多态现象。
  这句话很绕,直接看例子:
  class Father{
  private int i = 5;
  public Father() {
  System.out.println("Father's i is " + this.i);
  test();
  }
  public void test(){
  System.out.println(this.i);
  }
  }
  class Son extends Father{
  private int i = 55;
  public Son() {
  System.out.println("Son's i is " + this.i);
  }
  @Override
  public void test() {
  System.out.println(this.i);
  }
  }
  public class Test {
  public static void main(String[] args) {
  new Son();
  }
  }
  class Father{
  private int i = 5;
  public Father() {
  System.out.println("Father's i is " + this.i);
  test();
  }
  public void test(){
  System.out.println(this.i);
  }
  }
  class Son extends Father{
  private int i = 55;
  public Son() {
  System.out.println("Son's i is " + this.i);
  }
  @Override
  public void test() {
  System.out.println(this.i);
  }
  }
  public class Test {
  public static void main(String[] args) {
  new Son();
  }
  }
  结果是:
  Father's i is 5
  0
  Son's i is 55
  结合第一点,构造方法调用之前,首先是new指令创建了一个对象,并将各个成员初始化为其默认值。下面看构造方法的调用过程。子类构造方法会调用父类构造方法,父类构造方法首先打印Father's i is 5。然后调用test()方法,注意,我们创建的是Son类的对象,所以test()方法调用的是Son类定义的test()方法,也就是说发生了多态。我们再去看Son类中test方法的实现,就是简单的输出this.i,为什么是0呢,别忘了我们还没有执行子类的构造方法啊,所以此时子类的i还是new指令初始化得到的0。好,test()方法执行完了,总算回到子类构造方法继续执行,先把i赋值为55,下面的输出语句Son's i is 55也就不难理解了。
  在构造方法中调用方法要特别注意这种多态现象。
  这种现象和c++里的现象是不同的。在C++中,如果在父类的构造函数中调用虚方法的话,调用的是父类定义的版本,不会发生多态现象。但一个有趣的现象是,C++的经典书籍和Java的经典书籍竟然都建议不要在构造方法里面调用多态方法,因为现象并不是你期待的!这就奇怪了,难道C++程序员和Java程序员天生就有相反的期待吗?
内容概要:本文设计了一种基于PLC的全自动洗衣机控制系统内容概要:本文设计了一种,采用三菱FX基于PLC的全自动洗衣机控制系统,采用3U-32MT型PLC作为三菱FX3U核心控制器,替代传统继-32MT电器控制方式,提升了型PLC作为系统的稳定性与自动化核心控制器,替代水平。系统具备传统继电器控制方式高/低水,实现洗衣机工作位选择、柔和过程的自动化控制/标准洗衣模式切换。系统具备高、暂停加衣、低水位选择、手动脱水及和柔和、标准两种蜂鸣提示等功能洗衣模式,支持,通过GX Works2软件编写梯形图程序,实现进洗衣过程中暂停添加水、洗涤、排水衣物,并增加了手动脱水功能和、脱水等工序蜂鸣器提示的自动循环控制功能,提升了使用的,并引入MCGS组便捷性与灵活性态软件实现人机交互界面监控。控制系统通过GX。硬件设计包括 Works2软件进行主电路、PLC接梯形图编程线与关键元,完成了启动、进水器件选型,软件、正反转洗涤部分完成I/O分配、排水、脱、逻辑流程规划水等工序的逻辑及各功能模块梯设计,并实现了大形图编程。循环与小循环的嵌; 适合人群:自动化套控制流程。此外、电气工程及相关,还利用MCGS组态软件构建专业本科学生,具备PL了人机交互C基础知识和梯界面,实现对洗衣机形图编程能力的运行状态的监控与操作。整体设计涵盖了初级工程技术人员。硬件选型、; 使用场景及目标:I/O分配、电路接线、程序逻辑设计及组①掌握PLC在态监控等多个方面家电自动化控制中的应用方法;②学习,体现了PLC在工业自动化控制中的高效全自动洗衣机控制系统的性与可靠性。;软硬件设计流程 适合人群:电气;③实践工程、自动化及相关MCGS组态软件与PLC的专业的本科生、初级通信与联调工程技术人员以及从事;④完成PLC控制系统开发毕业设计或工业的学习者;具备控制类项目开发参考一定PLC基础知识。; 阅读和梯形图建议:建议结合三菱编程能力的人员GX Works2仿真更为适宜。; 使用场景及目标:①应用于环境与MCGS组态平台进行程序高校毕业设计或调试与运行验证课程项目,帮助学生掌握PLC控制系统的设计,重点关注I/O分配逻辑、梯形图与实现方法;②为工业自动化领域互锁机制及循环控制结构的设计中类似家电控制系统的开发提供参考方案;③思路,深入理解PL通过实际案例理解C在实际工程项目PLC在电机中的应用全过程。控制、时间循环、互锁保护、手动干预等方面的应用逻辑。; 阅读建议:建议结合三菱GX Works2编程软件和MCGS组态软件同步实践,重点理解梯形图程序中各环节的时序逻辑与互锁机制,关注I/O分配与硬件接线的对应关系,并尝试在仿真环境中调试程序以加深对全自动洗衣机控制流程的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值