ncyu_phyedu 板


LINE

封装的意义 物件导向程式设计的原则之一, 是让实作和界面分开, 以便让同一界面但不同的实作的物 件能以一致的面貌让外界存取, 为了达到此目标, java允许设计人员规范类别成员以及类 别本身的存取限制。 类别成员的存取 所谓封装(Encapsulation),是指class A的设计者可以指定其他的class能否存取A的某个 member。Java定义了四种存取范围: private:只有A自己才可以存取, 使用keyword private package:只有和A同一个package的class才可以存取, 没有相对应的keyword protected:只有同一个package或是A的子类别才可以存取, 使用keyword protected public:所有的class都可以存取, 使用keyword public public class EncapsulationExample { private int privateVariable; int packageVariable; protected int protectedVariable; public int publicVariable; private int privateObjectMethod() {} int packageObjectMethod() {} protected int protectedObjectMethod(); public int publicObjectMethod(); static private int privateClassMethod() {} static int packageClassMethod() {} static protected int protectedClassMethod(); static public int publicClassMethod(); } 如果member的前面没有private,protected,public其中一个修饰字,则该member的存取范 围就是package。从以上的叙述,读者可以推知这四种存取范围的大小是public > protected > package > private。 Package的定义 所谓package,可以想成是在设计或实作上相关的一群class。要宣告某class属於某 package,其语法为 package myPackage; public class MyClass { } 如果没有宣告package的话,如下面这两个class,就会被归类为「匿名」的package: // in file ClassA.java public class ClassA { public static void main(String[] argv) { ClassB x = new ClassB(); } } // in file ClassB.java public class ClassB { } 为了让JVM在执行期间能够找到所需要的class,同一个package的class会放在同一个目录 下。不过只知道目录的名称还不够,还需要指定该目录在档案系统内的路径。classpath这 个环境变数是由多个以分号隔开的路径所组成,JVM透过classpath配合package的名称就可 以找到所需要的class。如果我们只用到Java标准的程式库,则不需要指定classpath。指 定classpath环境变数时,要特别注意的是,不要忘了把.(代表目前的工作目录)放到最前面 ,否则就找不到「匿名」package里的class(别忘了绝大部分简单的范例都没有宣告 package,所以都是匿名的)。 classpath=.;n:\计网中心系统组\project; classpath里除了路径外,也可以指定zip或jar(java archive format)格式的档案。zip和 jar可以把目录及其子目录内的档案都压缩起来,因此可以透过这类档案抓到所需的class 档。 classpath=.;c:\mylib.zip;c:\otherlib.jar;n:\计网中心系统组\project; package的宣告可以用.号构成复杂的package tree。 package mylib.package1 public class A {} package mylib.package2 public class B {} 属於mylib.package1的class会放在mylib目录下的package1目录内。Java所提供的标准应 用程式介面(Application Programming Interface, API)就是一个复杂的package tree。 同一个.java档里面, 可以定义好几个class, 但最多只能有一个宣告为public class。此 限制是因为java希望每一个编译的单元(.java档)都有唯一的界面宣告。那麽public class和class的区别何在? non public class只能给同一个package内的其他class引用, public class则可以给任何class引用。 Package的引用 假如Class A用到package myPackage里的Class B, 为了检查A使用到B的部分是否符合B的 原始定义, 诸如方法存不存在, 参数正不正确等问题, Compiler必须引入class B的定义 , 以便进行编译时期的检查。引入的语法为 import myPackage.B; 这里要强调的是, import指令告知Compiler在Compiler time所要检查的类别定义在哪里 。但有时候我们编译的环境和执行的环境可能不同, 例如编译时用JDK 1.4, 执行时却用 JDK 1.2, 若程式使用到JDK 1.4才有的API, 那麽会在执行期间产生错误。 有时候我们会引用相当多个同属某package的类别, 如果要一个一个import, 会很烦人, 因此Java允许我们使用万用字元*来代表某package里的所有class: import myPackage.*; public class A { public static void main(String[] argv) { B x = new B(); } } 眼尖的读者会发现我们并没有import String的定义啊, 怎麽都没有问题? 由於写程式多 多少少都会用到一点系统提供的程式库, 如果连很简单的程式都要import一堆class, 也 真烦人。因此Java Compiler会自动帮我们引入java.lang.* public class Hello { public static void main(String[] argv) { System.out.println("Hello World."); } } 就等同 import java.lang.*; public class Hello { public static void main(String[] argv) { System.out.println("Hello World."); } } 由於class是放在类似树状结构的package tree里面, 因此引用的class应该加上完整的 package路径才是全名, 例如 public class Hello { public static void main(java.lang.String[] argv) { java.lang.System.out.println("Hello World."); } } 只要不会造成混淆, 一般我们都使用省略package路径的class简称。但是如果我们 import P1和P2两个package, 而这两个package碰巧都定义了同名的class A, 则用到A的 地方就比需以P1.A和P2.A来区别了。 下面的程式码哪里有错? package p1; public class Access { private static void f1() {} static void f2() {} protected static void f3() {} public static void f4() { Access.f1(); } } package p1; public class Example1 { public static void main(String[] argv) { Access.f1(); Access.f2(); Access.f3(); Access.f4(); } } package p2; import p1.*; public class Example2 { public static void main(String[] argv) { Access.f1(); Access.f2(); Access.f3(); Access.f4(); } } package p1; public class Example3 extends Access { public static void main(String[] argv) { Access.f1(); Access.f2(); Access.f3(); Access.f4(); } } package p2; import p1.*; public class Example4 extends Access { public static void main(String[] argv) { Access.f1(); Access.f2(); Access.f3(); Access.f4(); } } Java档和Class档的相依性 传统程式开发的流程是Compile个别Source Code,然後Link所有的Object Code成为执行档 。对大型的应用程式来说,常见的问题之一是如何确定Link时所需的Object Code是由最新 的Source编译而来?尤其模组间存在相依性,如模组A可能用到模组B里的函数,如果B的函数 有修改参数,则A模组也要重新编译。换句话说单看source code和object code的产生时间 是不行的。最简单的方法就是在Link前将所有的Source Code重新编译一次,但这样做有以 下几个问题: 重新编译大型专案全部的程式码可能会浪费不少时间 要对每个Source File下达编译指令,不但费时,而且容易遗漏。即使写个批次程式,也要随 时记得纳入新的原始档 由於这些问题的存在,某些原始码管理系统便因应而生,例如UNIX上的SCCS(Source Code Control System)。Java Compiler具有下面两个功能,可以在没有原始码管理系统的情况 下,也能解决上述问题: 可使用javac *.java来编译目前目录下的所有java档案 编译A.java时,会自动检查A所用到的其他class B,比较B.java和B.class的产生时间,如果 B.java比较新则B.java就会被重新编译 如果应用软体只有单一的进入点,例如class A的public static void main(String[] argv),则只要编译A.java就会自动编译其他需要重新编译的.java档。如果应用软体有两 个以上的进入点,如网路程式的client端和server端的进入点会不一样,只要写个批次档编 译相关进入点的.java档即可。 用Link List实作Stack Link List Stack 示意图(点图放大) public class Stack { private Node head; private int size; class Node { Object data; Node next; } public void push(Object s) { Node tmp = new Node(); tmp.next = head; tmp.data = s; size++; head = tmp; } public Object pop() { Object tmp = head.data; head = head.next; size--; return tmp; } } -------------------------------------------------------------------------------- Link List Stack Push Step 1(点图放大) Link List Stack Push Step 2(点图放大) Link List Stack Push Step 3(点图放大) Link List Stack Pop(点图放大) -------------------------------------------------------------------------------- public class Example { public static void main(String[] argv) { Stack s1 = new Stack(); Stack s2 = new Stack(); s1.push("abc"); s1.push("def"); s2.push("123"); s2.push("456"); } } 用Link List实作Queue public class Queue { private Node head, tail; private int size; class Node { Object data; Node next; } public void put(Object s) { Node tmp = new Node(); tmp.data = s; if (tail != null) { tail.next = tmp; } else { head = tmp; } tail = tmp; size++; } public Object get() { Object tmp = head.data; head = head.next; if (head == null) { tail = null; } size--; return tmp; } } --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.58.22.74







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:Tech_Job站内搜寻

TOP