2010-03-28 86 views
2

我不确定OOP中的一些事情。面向对象编程如何工作?

如果我有Class1,其中有一些私人的领域,例如private Field field1,使

getField1() { 
    return field1; 
} 

然后我有一些类的构造函数

public Class2 (Field field) { 
    someMethod(field); 
} 

然后我调用的Class2的构造函数CLASS3喜欢:

Class2 cl = new Class2(instanceOfClass1.getField1()); 

而且现在的曲estion:我是否与field1instanceOfClass1someMethod(field)

+1

这是Java或C#或通用OOP? – 2010-03-28 12:35:35

+0

我认为这并不重要,但它是java。 – venom 2010-03-28 12:40:10

+3

它可能很重要。 Java按值传递所有内容,而C/C++可以使用指针和引用。 – 2010-03-28 13:52:52

回答

5

这取决于field是否是一个值或一个参考。当作为参数传递

值类型被复制。引用类型不是;该函数简单地传递一个指向原始值的“引用”,并且它所做的任何更改都会反映到原始值中。

无论是给定类型的值或引用取决于特定的编程语言。一般来说,基本整数和布尔类型通常是值类型,以及其他一切是在空气中 - 有些语言让字符串值,和其他人把他们当作参考等

编辑:既然你提到你使用Java,这里是一个简短的程序演示值类型和引用类型:

class ClassOne { 
    public int myInt; 
} 

class ClassTwo { 
    public int myInt; 
    public ClassTwo(ClassOne c) 
    { 
     myInt = c.myInt; 
     c.myInt = 3; 
    } 
} 

public class main 
{ 
    public static void main(String[] args) 
    { 
     ClassOne c = new ClassOne(); 
     c.myInt = 1; 
     System.out.println("C1: " + c.myInt); 

     ClassTwo c2 = new ClassTwo(c); 
     System.out.println("C2: " + c2.myInt); 
     System.out.println("C1: " + c.myInt); 

    } 
} 

运行这个程序会给出输出:

C1: 1 
C2: 1 
C1: 3 

在这个程序中,ClassOne和ClassTwo都包含一个整数字段 - 一个值类型。 ClassTwo在其构造函数中接受一个ClassOne参数 - 一个引用类型,并根据它给出的ClassOne对象的值设置它自己的整数字段,然后更改ClassOne对象的值。

由于类是引用类型,因此在ClassTwo构造函数中更改ClassOne对象会导致原始对象被更改。 (在这里的主要功能,这是c。)但由于整数是值类型,即使c2在其构造函数中更改c.myInt的值,因为它预先设置其自己的值,c2.myInt不受影响:它保留原始数字,因为它被复制而不是被引用。

希望这有助于明确了一点东西。

+0

当我创建ArrayList 和私人MyClass cl;在Java中,都是参考? – venom 2010-03-28 12:43:13

+0

Java中的类类型始终是引用类型。如果在类对象中有一个字段,并且将该字段值传递给另一个方法,那么当它修改了您给它的值时,它将修改原始字段指向的同一个类对象。有些类被设计为本地不可变,以防止这种混淆 - 字符串是最明显的例子。字符串一旦创建,就不会改变 - 任何可能改变它们的操作(例如toUpperCase或substring)都会返回一个新的String实例。 – 2010-03-28 13:02:31

2

您正在处理包含在其中的值。如果它是一个可变对象,那么是的,可以从外部更改Class1实例的状态,这违反了数据保护原则。这就是为什么你应该在返回它们之前复制可变类型。

+0

但是如果我需要完全跟踪该实例,并且someMethod(field)将该字段放到某个全局查找中?如何通过复制来解决它? – venom 2010-03-28 12:39:44

+0

如果您制作可变对象的深层副本,则对象的任何突变都不会影响副本。 – 2010-03-28 12:41:06

0

我不得不重读你的问题两次或三次,以确保我明白你的要求。

总括:

  • 存在被发送回由它的getField1()方法的Class1其中包含一个字段的属性(类型字段的?)。
  • 那么Class2显然有一个构造函数,它接受Field类型的对象参数并且包含一个使用Field实例触发本类中的本地方法的方法。
  • 然后,您使用第三个类来实例化Class2,并使用来自Class1实例的getField1()方法使用Field实例对其进行初始化。

在Java的情况下,假设您已经完成了必要的实例化,这意味着在整个过程中将使用Class1中的Field实例。你可以使用System.out.println()(这会给你带有一系列奇怪数字的@符号)或使用所有对象通用的a.equals(b)方法来验证。

这里是关于按值传递对象一个有趣的链接: http://www.javaranch.com/campfire/StoryPassBy.jsp