Java学习注意事项

一个Java文件中可以包含多个类。

如果有public类,则文件名必须和public类一样。

例如:

 1 class Pie {
 2    void f(){
 3        System.out.println("Pie.f()");
 4    }
 5 }
 6 
 7 class Cake {
 8    public static void main(String[] args){
 9        Pie x = new Pie();
10        x.f();
11    }
12 }
13 
14 class Cake1 {
15        public static void main(String[] args){
16            Pie x = new Pie();
17            x.f();
18        }
19     }

该文件名可以是Cake2.java或者其它。但如果该文件中有public 类,则文件名必须和public 类名一样。

上述文件编译产生如下的文件:

编译和运行命令如下:

 

1 关于类的访问权限控制:public 或者什么都不写(包访问权限,其它包的类不能访问该类)。

2 方法和字段的访问权限顺序从大到小:Public,  protected,  默认(包访问权限),  private。

2.1 protected 修饰的成员,如果其它package中的类继承了该类,就可以访问该成员。比默认的权限高。

 

3 使用final关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的。

4 由于final变量和static变量可以说都只能存一个数据,他们惟一的区别是static变量是属于类的,是类变量,只会被加载一次。

5 final和abstract 修饰的类,第一个不能继承,第二个继承必须实现存在的abstract方法。

6 abstract方法所在的类必须用abstract修饰。abstract修饰的类不能实例化,可以不存在抽象方法。

 

 

关于final

使用final的原因有两个。效率/设计。早期的编译器会针对final方法,进行特殊的优化。但是现在的编译器不推荐用户使用final关键字,

编译器和JVM会去处理相关的效率问题。

特别的,final方法不能被覆盖。因为private方法是不能够继承的,所以private 方法隐式的是final的。

"覆盖"只有在某方法是基类的接口的一部分时才会出现。如果某方法为private,它就不是基类的接口的一部分。

由于private方法无法触及而且能有效的隐藏,所以除了把它看成是因为它所属的类的组织结构的原因而存在外,其他任何事物都不需要考虑到它。

 

继承的初始化顺序

 

 1 package reusing;
 2 class Insect{
 3     private int i = 9;
 4     protected int j;
 5     public Insect() {
 6         System.out.println("i = " + i + ", j = " + j);
 7         j = 39;
 8     }
 9     private static int x1 = printInit("static Insect x1.initalized");
10     static int printInit(String s){
11         System.out.println(s);
12         return 47;
13     }
14 }
15 public class Beetle extends Insect{
16     private int k = printInit("Beetle.k initalized");
17     public Beetle(){
18         System.out.println("k = " + k);
19         System.out.println("j = " + j);
20     }
21     private static int x2 = printInit("static Beetle x2.initalized");
22     public static void main(String[] args){
23         System.out.println("Bettle Constructor");
24         Beetle b = new Beetle();
25     }
26 
27     /*
28      * static Insect x1.initalized
29      * static Beetle x2.initalized
30      * Bettle Constructor
31      * i = 9, j = 0
32      * Beetle.k initalized
33      * k = 47
34      * j = 39
35      * 
36      */
37 }
继承初始化顺序

 构造器中方法调用初始化特点及原则

 1 package ploymorphism;
 2 
 3 class Glyph {
 4     void draw() {
 5         System.out.println("Glyph.draw()");
 6     }
 7 
 8     Glyph() {//1-0-0
 9         System.out.println("Glyph() before draw()");//2
10         draw();//3
11         System.out.println("Glyph() after draw()");//5
12     }
13 }
14 
15 class RoundGlyph extends Glyph {
16     private int radius = 1;//6
17 
18     RoundGlyph(int r) {//1-0
19         radius = r;//7
20         System.out.println("RoundGlyph.RoundGlyph(), radius = " + radius);//8
21     }
22 
23     void draw() {//3-0
24         System.out.println("RoundGlyph.draw(), radius = " + radius);//4
25     }
26 }
27 
28 public class PolyConstructors {
29     public static void main(String[] args) {
30         new RoundGlyph(5); //1
31     }
32 }
33 
34 /*
35  * 1) 在其它任何事物发生前,将分配给对象的存储空间初始化成二进制的零
36  * 2) 调用基类构造器。如上例,调用被覆盖后的draw()方法(要在调用RoundGlyph构造器之前调用),
37  *    由于步骤1的缘故,我们此时发现radius的值为0
38  * 3) 按照声明的顺序调用成员的初始化方法
39  * 4) 调用导出类的构造器的主题。
40  * 
41  */
42 /*
43  * 编写构造器的准则
44  * 
45  * 用尽可能简单的方法使对象进入状态;
46  * 如果可以的话,尽量避免调用其它方法;
47  * 在构造器内唯一安全能够调用的方法是基类中的final(private也自动是final)方法;
48  * 应该朝着上述的方向努力。
49  * 
50  */
51  
构造器

 

Java中的堆栈实现,用到内部类

 1 class LinkedStack<T> {
 2     /*
 3      * 内部类模拟堆栈,Node<U>也是泛型,它拥有自己的类型参数
 4      */
 5     private static class Node<U> {
 6         U item;
 7         Node<U> next;
 8 
 9         Node() {
10             item = null;
11             next = null;
12         }
13 
14         Node(U item, Node<U> next) {
15             this.item = item;
16             this.next = next;
17         }
18 
19         boolean end() {
20             return item == null && next == null;
21         }
22     }
23 
24     private Node<T> top = new Node<T>();
25 
26     public void push(T item) {
27         top = new Node<T>(item, top);
28     }
29 
30     public T pop() {
31         T result = top.item;
32         if (!top.end()) {
33             top = top.next;
34         }
35         return result;
36     }
37 
38     public static void main(String[] args) {
39         LinkedStack<String> lss = new LinkedStack<String>();
40         for (String s : "Phaser on stun!".split(" ")) {
41             lss.push(s);
42         }
43         String s;
44         while ((s = lss.pop()) != null) {
45             System.out.println(s);
46         }
47     }
48 }
堆栈功能实现

 

Java能不能实例化访问私有方法?

1  该问题要分情况的,如果在类定义中实例化该对象,则可以通过引用访问该对象的所有内容。

2  如果是在类的定义外实例化,则只可以访问非私有的属性。

java父类的构造器私有了, 怎么继承?

private只能本类中使用,其他的都用不了,所以也不能继承。
不过可以通过曲线救国
在父类里提供一个方法,该方法返回父类的对象,然后子类这时可以通过继承方法获取父类的对象。
一般构造器私有比较常用的就是单态了(工具类有的也这样用或者其他)

Java考题练习,继承、访问权限、多态、初始化
 1 class Test {
 2     private int day;
 3 
 4     private Test(int d) {
 5         day = d;
 6     }
 7 
 8     private void print() {
 9         System.out.println("I am in Test");
10     }
11 }
12 
13 class DemoTest extends Test {
14     private DemoTest() {
15         super(2);
16     }
17 
18     public void print() {
19         System.out.println("I am in DemoTest");
20     }
21 
22     public static void main(String[] args) {
23         DemoTest test = new DemoTest();
24         test.print();
25     }
26 }
27 
28 /*
29    编译不通过,父类构造器私有,不能继承。把Test的private去掉即可
30    多态在这里没有发生,子类不能够覆盖父类的私有方法
31 */
考题

 文件Parcel2还有内部类,编译后是如下的三个class文件






StringBuffer的作用以及赋值修改
观察下面的代码
 1 package sunjava;
 2 
 3 public class Foo {
 4     static void operate(StringBuffer a, StringBuffer b){
 5         a.append(b);
 6         b = a;
 7     }
 8     public static void main(String[] args){
 9         StringBuffer a = new StringBuffer("A");
10         StringBuffer b = new StringBuffer("B");
11         operate(a, b);
12         System.out.println(a + "," + b);
13     }
14 /*
15  * append 函数的作用改变a的值,但是b = a 不能够改变b的值
16  * 
17  * outPut:
18  * AB,B
19  * 
20  */
21 }
View Code

 和下面的代码对比,会得出更加直观的效果。

 1 package sunjava;
 2 
 3 public class No6 {
 4    public static void stringReplace(String textString){
 5        textString = textString.replace("j", "i"); //testString 新赋值了一个,与原来的无关
 6    }
 7    public static void bufferReplace(StringBuffer textBuffer){
 8        textBuffer.append("C"); //textBuffer在原来的上面加了一个C,源字符串被修改
 9    }
10    
11    public static void main(String[] args){
12        String textString = new String("java");
13        StringBuffer textBuffer = new StringBuffer("java");
14        stringReplace(textString);
15        bufferReplace(textBuffer);
16        
17        System.out.println(textString + textBuffer);
18    }
19    /*
20     * 注意StringBuffer类和String之间的区别
21     * 
22     * outputs:
23     * 
24     * javajavaC
25     */
26 }
StringBuffer

 

  •  注意Overrride和Overload之间的不同点
  • Java 内部类 分四种:成员内部类、局部内部类、静态内部类和匿名内部类。
  • java成员变量的初始化顺序

 

 

 

posted @ 2014-11-20 09:32  kongmeng  阅读(202)  评论(0编辑  收藏  举报