显示标签为“java”的博文。显示所有博文
显示标签为“java”的博文。显示所有博文

2007年3月21日星期三

重拾java(3):继承

❁java不支持多继承

❁子类不能访问父类中声明为private的类成员

❁java与C++中均一样,父类引用不能访问仅在子类中定义的函数或变量:
public class t2 {
public static void main(String args[]) {
F p = new S();
int i = p.s; // wrong
}
}

class F {
int f;
}

class S extends F {
int s;
}
❁super()必须永远是一个子类构造函数内执行的第一条语句。如下面的程序将会报错:
class S extends F {
int s;
S() {
int u;
super(); // Wrong! Constructor
call must be the first
statement in a constructor
int k;
}
}

因为构造函数按派生顺序,从超类到子类被调用。

❁如下程序例1。父类中的变量虽被覆盖,但p仍访问的是父类变量。而父类中的方法却被覆盖,因此p.pr()访问的是子类函数,类似于C++中的虚函数。这一点非常奇怪。因为在C++中,不管是变量还是函数,它们都是统一的,要覆盖就都会被覆盖,像这种动态的函数调用必须通过virtual来声明。另:C++中类中变量不能为virtual,只能是函数才可以用virtual修饰。这也许是java中要如此分开对待的原因吧。
public class t2 {
public static void main(String args[]) {
F p = new S();
System.out.println(p.i); // 1 父亲中的变量
p.pr(); // In S... 儿子的方法
}
}

class F {
int f;
int i;
F() {
;
}
void pr()
{ System.out.println("In F..."); }
}

class S extends F {
int s;
int i;
S() {
super.i = 1;
i = 2;
}
void pr()
{ System.out.println("In S..."); }
}

例2:
public class t2 {
public static void main(String args[]) {
F p1 = new S();
System.out.println(p1.i); // 1

S p2 = new S();
System.out.println(p2.i); // 2
}
}
class F {
int f;
int i;
F() {
;
}
}
class S extends F {
int s;
int i;
S() {
super.i = 1;
i = 2;
}
}
❁抽象abstract:
子类必须实现父类中所有的抽象函数。
包含一个或多个抽象方法的任何类也必须被声明为抽象的。
不能声明抽象构造函数或抽象静态方法。
抽象类虽不可被实例化,但可以被用来创建对象引用。
同C++中virtual类似,abstract不能用来修饰类中变量,而只能是函数。

重拾java(2)

1、类型
(1) 自动类型提升
byte a = 40;
byte b = 50;
byte c = 100;
int d = a * b / c; // a、b、c在计算中,
其类型自动提升为int型
System.out.println(d);

byte e = 5;
e = e * e; // wrong. Type mismatch: cannot
convert from int to byte
byte a = 64, b;
b = (byte)(a << 2);

一个浮点文字自动为double,如:
float ff = 3.55; //wrong
float f = 5 / 3 + 7.88; //wrong! Type mismatch:
cannot convert from
double to float

应该为:
float ff = 3.55F;
float f = 5 / 3 + 7.88f; //right!

2、数组
(1) 数组是作为对象实现的,因此有类内变量length:
int m[][] = new int[4][];
m[0] = new int[5];
m[1] = new int[8];
System.out.println("m[][] = " + m.length); // 4
System.out.println("m[0] = " + m[0].length); // 5
//System.out.println("m[1][] = " + m[1][].length);
// wrong
//System.out.println("m[1][3] = " + m[1][3].length);
// wrong
//System.out.println("m[3] = " + m[3].length);
// wrong

(2) 数组越界:运行时错误(C/C++不提供运行时边界检查)
int m[] = new int[2];
m[0] = 0;
m[1] = 1;
m[2] = 2; //wrong

(3) 同C/C++,“int n[] = { 1, 2, 3, 4, };” 是正确的(即末尾可多一个逗号)。

(4) java支持多维不等数组。如:
int twoD[][] = new int[3][];   // 仅需第一维指定内存
twoD[0] = new int[5];
twoD[1] = new int[3];
twoD[2] = new int[1];
3、运算符
(1) java中,“%”运算符可以用于浮点类型,而C/C++不能。如:
double d = 22.33 % 2.34;
(2) >> :向右移 >>> :向右移,左补零
byte类型的值最高位若为1,则>>>对其是不可能的。如:
byte b = 0xf1; 则 b>>4为0xff,b>>>4为0xff,(b & 0xff)>>4为0x0f。

(3) java中对boolean类型的值来说有运算符&(逻辑与)与&&(短路与)的区分(|与||同)。

(4)
float f = 3;
int i = 3;
if(i == f)
  System.out.println("Yes"); // This will be printed
else
  System.out.println("No");

4、程序控制语句
(1) 在程序控制语句中,除了for语句可以使用逗号作为分隔符外,其他的地方不能使用逗号。如:
int k = 0;
int i = true ? (k=3,k) : (k=4,k);
// 错误,Syntax error on token
",", invalid AssignmentOperator
这一点与C/C++不同。

(2) switch语句中,若default语句不在最后,其后也应该跟一个break语句。如:
int i = 4;
int k = 0;
switch(i)
{
  default :
    k = 4;
  case 1:
    k = 1;
    break;
  case 2:
    k = 2;
    break;
  case 3:
    k = 3;
    break;
}
System.out.println(k);

将打印出“k=1”。

(3) java中break、continue后可以跟一个标号。如:
one:for(int j=0;j<100;j++)
{
if(j==10) break one;
System.out.println(j + " ");
}
而在C/C++中不可以。

(4) 像“7 + 8;”这样的无意义的语句在java中是不允许的;而C/C++中可以。

5、函数
(1) 关于重载,java与C++中都是允许的,而在C中是不允许的。
在C++中,看下面这个例子:
#include <iostream.h>

//函数1
//void f()
//{ printf("haha1\n"); }

//函数2
void f(int i)
{ printf("haha2\n"); }

int main()
{
int g = (int)f; //(*)
((void (*)())g)();

return 0;
}
若不将函数1、2中的一个注释掉,赋值语句(*)处将会报错,因为在这里产生了二义。而只留有一个函数即没有重载,就没有事。

6、类
(1) java中默认为近似public的属性,而C++中为private。

(2) 关于类实例的声明:
java中:
X x = new X();  // X x = new X;的形式是错误的
x.i = 0;
C++中:
X x = new X(); 或 X x = new X;
x->i = 0;

X x; // 若没有构造函数或构造函数无参数,则 X x();的形式是错的的
x.i = 0;
(3) C++中类定义结尾必须有分号,而java可有可无。

(4) java中finalize方法与C++的析构函数是有区别的。protected void finalize()函数仅在垃圾收集时被调用,而当一个对象在作用域外时,她是不会被调用的。
这意味着你不知道什么时候或是否会执行finalize()。因此,你的程序必须提供其他的方法来释放被对象使用的系统资源。
这与C++是不同的。C++的析构函数在对象处于作用域外时被调用。
java中因为所有的对象是使用new动态分配的,因此不需要担心关于对象在作用域范围之外的问题。因为对象创建时所在的方法终止了,
对象将继续存在,只要在你的程序中的某处存在一个此对象的引用。当不存在它的引用时,下次垃圾收集起作用时,将重新收回这个对象。

(5) 在C++中,如下:
class X {
public:
int i;
};

int main()
{
X x();

return 0;
}
此x将被认为是函数的声明。如:
class X {
public:
int i;
};

int main()
{
X x();
x();
return 0;
}

X x()
{
cout << "haha\n":
...
}
(6) 在函数中的参数,简单类型是按值传递,而对象则按引用传递

(7) 关于类中的static
声明为static的方法有几条限制:
─它们仅可以调用其他static方法;
─它们只能访问static数据;
─它们不能以任何方式引用this或super。
关于static块,这个块仅在该类被第一次加载时执行一次。例:
public class t2 {
static int i;
public static void main(String args[]) {
System.out.println("Start in main");

Y y = new Y();

System.out.println("End in main");

y = null;
}

}

class Y {
int i;
static int a = 3;
static int b;
static {
System.out.println("Static block");
b = a * 4;
}
Y() {
System.out.println("Con...");
}
protected void finalize() {
System.out.println("decon...");
}
}
打印:
Start in main
Static block
Con...
End in main

(8) 关于类嵌套(C++中没有)
A:外壳类 B:核类
A可知B,而A外的作用域不可知B。
B可访问A的成员,包括私有成员;A不能访问B的成员。
B可分为静态的(修饰以static)和非静态的(内部类)。静态的B必须通过一个对象来访问A的成员,而不能直接引用之;而非静态类则可以
访问A的所有成员,并且可以像A的其他非静态成员那样以同样的方式直接引用它们。
另外,嵌套类可以定义在任何块内,比如函数、for循环内等等。

(9) String
String ss = "wre"+"fsd";  // 对
String ss = "wre""fsd"; // 错,虽然在
C/C++中可以这样
(10) 与C/C++不同,java的命令行参数计数不是从所运行的程序名开始的。如:
class CommandLine {
public static void main(String args[])
{
for(int i=0;i<args.length;i++)
{
System.out.println("args["+i+"]:"+args[i]);
}
}
执行 # java CommandLine this is a test 100 -1
将打印出
args[0]:this
args[1]:is
args[2]:a
args[3]:test
args[4]:100
args[5]:-1

2007年3月19日星期一

重拾java

上星期六去参加了IBM的研究生实习招聘的笔试。两份卷子,其中一份厚厚一叠都是java。作下来很不爽,java几乎都忘光了。所以决心重拾java。晚上在我的ubuntu上弄好了eclipse,然后看了点书,作笔记如下(大部分是java与C/C++间的比较):
1、
java和C中,变量名中可以使用$,如“int $hu;”。
2、
java是强类型的,甚至比C/C++还严格。如:
在java中,int i = 4.5; // 错误
而在C中,int i = 4.5; // 可以
3、
java不支持无符号的正整数。
java中byte(8)、short(16)、int(32)、long(64)其宽度是固定的,不随目标机器的不同而不同 。
java中char是16位(无符号数)的Unicode表示。
4、
“boolean b = true;
System.out.print("boolean true is : " + b);”
将打印出“true”而不是“1”。
5、
关于char型变量的数字表示,在java与C/C++中有一些区别:


javaC/C++
八进制\ddd\ddd
十六进制\uhhhh\xhh
6、
对于java的字符串,它们必须在同一行开始和结束,没有像在其他语言中的行连续转义(如C/C++中的“\”)序列(对于很长的字符串,要换行可以使用+号连接)。
7、
关于块作用域,在java中,你不能声明一个变量为与外部作用域的变量一样的名称。如下面的程序:
class ScopeErr {
public static void main(String arg[]) {
int bar = 1;
{ // creates a new scope
int bar = 2; // Compile-time error - bar already defined!
}
}
}
而这种情况在C/C++中是合法的。