java是一种混合语言,既支持面向过程又支持面向对象。同样如此的还有C++,但是java和C++相比,更加适合面向对象的编程,因为java代码全部都由类组成,是更加彻底的面向对象语言。因此,掌握好java的类对于学习java来说至关重要!
和大多数面向对象语言一样,java类的定义也是关键字class,而且class只有一种含义(和c++就不同了,c++中的class还有模板的意思),就是类的定义!一个典型的java 类的定义如下:
public class Demo {
private int data;
public int getData() {
return data;
}
public void setData(int data) {
this.data = data;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
类名的原则和标识符的原则一样,应以字母、下划线、美元符开头,后跟字母、下划线、美元符或者数字,标识符对大小写敏感,标识符没有长度限制,不能把关键字和保留字作为标识符。注意这里的字母是可以使用大多数汉字,因为java的编码是基于Unicode字符集的,在java中一个字符占两个字节(任何平台都是这样,java的跨平台特性保证了这一点),所以java的字符包括汉字。
在类名后面可选的是是否继承别的类,用extends关键字实现,例如class Demo extends PreDemo{ },定义类Demo继承自类PreDemo。这里还是可以和C++对比一下,在java中继承只有一种,c++的太复杂了,我也不会就不说了。而且java的继承是单继承,不像C++那样的没有限制。java中的如果没有显式继承别的类的话,这个类会默认继承Object。
在类名后面还可选的是是否实现别的接口,用implements关键字,实现一个接口需要实现这个接口中的所有方法,一个类可以实现多个接口,类似于c++中的多继承。
再说说java类的成员,成员有数据成员和方法,所有成员都有访问修饰符,访问权限从低高为:private 只能类内(内部类也可以访问)进行访问;default 类内和包内能够访问;protect 类内、包内和子类中能够访问;public任何地方都能访问。
类还有一种比较特殊的形式:内部类。内部类是定义在另一个类中的类。为什么使用内部类呢?其原因主要有一下几点:
1、内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据。
2、内部类可以对同一个包中的其他类隐藏起来。
3、当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。
内部类可以是静态static的,也可以被public,protected,default,private修饰,而外部类只能被public和default修饰;内部类是编译时的概念,一旦编译成功就会成为完全不同的两个类,对于一个使用Outer名字的外部类和一个使用Inner名字的内部类而言,编译完成后出现Outer.class和Outer$Inner.class两个类,所以内部类的成员变量和方法名字可以和外部类相同。
1、成员内部类
成员内部类就是作为外部类的成员,可以直接使用外部类得所有成员和方法,即使是私有成员。同时外部类想要访问内部类的所有成员和方法,则必须通过内部类的对象来获取。成员内部类不能有静态域和方法,因为成员内部类需要先创建外部类,才能创建他自己的,了解这一点就可以明白更多事情。
在成员内部类想要引用对象时,可以用外部类名.this来表示。
public class Outer {
public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.print("Outer.new");
inner = outer.getInner();
inner.print("Outer.get");
}
// 个人推荐使用getxxx()来获取成员内部类,尤其是该内部类的构造函数无参数时
public Inner getInner() {
return new Inner();
}
public class Inner {
public void print(String str) {
System.out.println(str);
}
}
}
2、局部内部类
局部内部类是指内部类定义在方法和作用域内,Thinking in Java给出了这两个例子
定义在方法内
public class Parcel4 {
public Destination destination(String s) {
class PDestination implements Destination {
private String label;
private PDestination(String whereTo) {
label = whereTo;
}
public String readLabel() {
return label;
}
}
return new PDestination(s);
}
public static void main(String[] args) {
Parcel4 p = new Parcel4();
Destination d = p.destination("Tasmania");
}
}
定义在作用域内:
public class Parcel5 {
private void internalTracking(boolean b) {
if (b) {
class TrackingSlip {
private String id;
TrackingSlip(String s) {
id = s;
}
String getSlip() {
return id;
}
}
TrackingSlip ts = new TrackingSlip("slip");
String s = ts.getSlip();
}
}
public void track() {
internalTracking(true);
}
public static void main(String[] args) {
Parcel5 p = new Parcel5();
p.track();
}
}
局部内部类也像别的类一样进行编译,但只是作用域不同而已,只有在该方法或条件的作用域内才能使用,退出这些作用域是无法引用的。
3、嵌套内部类
嵌套内部类就是修饰为static的内部类,不需要内部类和外部类之间的联系,就是说我们可以直接引用Outer.Inner,而不需要创建外部类对象。从技术上讲,嵌套内部类不属于内部类,
public class StaticTest {
private static String name = "javaJohn";
private String id = "X001";
static class Person{
private String address = "swjtu,chenDu,China";
public String mail = "josserchai@yahoo.com";//内部类公有成员
public void display(){
//System.out.println(id);//不能直接访问外部类的非静态成员
System.out.println(name);//只能直接访问外部类的静态成员
System.out.println("Inner "+address);//访问本内部类成员。
}
}
public void printInfo(){
Person person = new Person();
person.display();
//System.out.println(mail);//不可访问
//System.out.println(address);//不可访问
System.out.println(person.address);//可以访问内部类的私有成员
System.out.println(person.mail);//可以访问内部类的公有成员
}
public static void main(String[] args) {
StaticTest staticTest = new StaticTest();
staticTest.printInfo();
}
}
在静态嵌套类的内部不能直接访问外部类的非静态成员,由于这个原因,嵌套静态类使用的很少。静态内部类中可以有static成员。
4、匿名内部类
匿名内部类,顾名思义,没有名字的内部类。表面上看起来他们似乎有名字,实际那不是他们的名字。
A、继承式的内部类
class Car {
public void drive(){
System.out.println("Driving a car!");
}
}
class Test{
public static void main(String[] args) {
Car car = new Car(){
public void drive(){
System.out.println("Driving another car!");
}
};
car.drive();
}
}
结果输出了Driving another car! Car引用不是引用Car对象,而是Car匿名子类的对象。建立匿名内部类的关键点是重写父类的一个或多个方法,而且创建新的方法是多余的,父类的引用不可能调用父类本身没有的方法。
B、接口式的内部类
interface Vehicle {
public void drive();
}
class Test{
public static void main(String[] args) {
Vehicle v = new Vehicle(){
public void drive(){
System.out.println("Driving a car!");
}
};
v.drive();
}
}
上面的代码像是在实例化一个接口,事实并非如此,接口式的匿名类是实现了一个接口的匿名类,而且只能实现一个接口。
C、参数式的匿名类
class Bar{
void doStuff(Foo f){}
}
interface Foo{
void foo();
}
class Test{
static void go(){
Bar b = new Bar();
b.doStuff(new Foo(){
public void foo(){
System.out.println("foofy");
}
});
}
}
理解方式和上面的匿名类一样。
匿名类的介绍大概就这些了。
一个java类的构成也就这些了,当然学会java类远不止这么简单,我会在接下来的博客中对java的类进行更多的介绍。