概述
8.1.5 Object类
Java语言中有一个特殊类Object,该类是java.lang类库中的一个类,所有的类都是直接或间接地继承该类而得到的。即如果某个类没有使用extends关键字,则该类额比默认为java.lang.Object类的子类。所以,Object是所有类的源。常用方法:
public boolean equals(Object obj) 判断两个对象变量所指向的是否是同一个对象
public String toString() 将调用toString()方法的对象转换成字符串
public final Class getClass() 返回运行getClass()方法的对象所属的类
protected Object clone() 返回调用该方法的对象的一个副本
1.equals()方法
用于判断两个对象是否相等。可以在任何类中直接使用该方法。队友字符串的操作,Java运行时会维护一个字符串池,对于一些可共享的字符串对象,会先在字符串池中查找是否有相同的字符串内容。
”==“和equals()比较的方式是不同的。==比较两个变量本身的值,equals()用来比较两个变量所包含的内容是否相同。
2. toString()方法
toString()方法的功能是将调用该方法的对象的内容转换成字符串,并返回其内容,但返回的是一些没有意义的字符串。因此如果要用toString()方法返回对象的内容,可以重新定义该方法以覆盖父类中的同名方法以满足需要。
3. getClass()方法
因getClass()方法是Object中指定的方法,而Object类是所有类的父类,所以在任何类中均可调用这个继承而来的方法。该方法的功能是返回运行时的对象所属的类。
Class对象。
//filename: aPP8_8.java
class Person
{
protected String name;
public Person(String xm)
{
name=xm;
}
}
public class aPP8_8
{
public static void main(String[] args)
{
Person per=new Person("zhang_san");
Class obj=per.getClass();
System.out.println("The class to which the object per belongs is "+obj);
System.out.println("Whether the object per is an interface: "+obj.isInterface());
}
}
4.对象运算符instanceof
Object类中的getClass()方法返回的是运行时的对象所属的类,除此之外,还可以利用对象运算符instanceof来测试一个指定对象是否是指定类或它的子类的实例,若是,则返回true。
8.2 抽象类
类的继承关系中,子类继承父类的非私有成员。在Java语言中还可以创建专门的类作为父类,其目的是根据它的格式来创建和修改新的类。但是不能直接由抽象类创建对象,只能由抽象类派生出新的子类,再由其子类创建新的对象。
2.1 抽象类和抽象方法
抽象类是以abstract修饰的类,定义抽象类的语法如下:
abstract class 类名
{
声明成员变量;
返回值的数据类型 方法名(参数表)
{
.
.
.
}
abstract返回值的数据类型 方法名(参数表); ——抽象方法,在抽象方法里,不能定义方法体
}
在抽象类中的方法可分为两种:一种是以前介绍的一般的方法;另一种是”抽象方法“,是以abstract声明的方法,此方法只声明返回值的数据类型、方法名称和所需的参数,但是没有方法体。也就是说,抽象方法只需声明,而无需实现。
即用”;“结尾,而不是{},当一个方法为抽象方法时,意味着必须被子类所覆盖,否则子类仍然是抽象的。抽象方法声明修饰符static和abstract不能同时使用。抽象类的子类必须覆盖父类,或者自己也声明为抽象的。
抽象类中不一定包含抽象方法,但是声明抽象方法的类一定要声明为抽象类。抽象类本身并不具备实际的功能。
8.2.2 抽象类的应用
由于抽象类的目的是要根据它的格式来创建新的类,所以抽象类里的抽象方法并没有定义处理数据的方法体,而是要保留给由抽象类派生出的子类来定义。
//filename: App8_10.java
abstract class Shape
{
protected String name;
public Shape(String xm)
{
name=xm;
System.out.print("name:"+name);
}
abstract public double getArea();
abstract public double getLength();
}
class Circle extends Shape
{
private final double PI=3.14;
private double radius;
public Circle(String shapeName, double r)
{
super(shapeName);
radius=r;
}
public double getArea()
{
return PI*radius*radius;
}
public double getLength()
{
return 2*PI*radius;
}
}
class Rectangle extends Shape
{
private double width;
private double height;
public Rectangle(String shapeName, double width, double height)
{
super(shapeName);
this.width=width;
this.height=height;
}
public double getArea()
{
return width*height;
}
public double getLength()
{
return 2*(width+height);
}
}
public class App8_10
{
public static void main(String[] args)
{
Shape rect = new Rectangle("rectangle",6.5,10.3);
System.out.print(";area="+rect.getArea());
System.out.println(";length="+rect.getLength());
Shape circle = new Circle("circle",10.2);
System.out.print(";area="+circle.getArea());
System.out.println(";length="+circle.getLength());
}
}
但是在cmd里面一直有报错,尚不清楚什么原因
在Shape 中找不到 main(String[]) 方法
8.3 接口
接口(Interface)是Java语言提供的一种重要功能,它的结构与抽象类非常相似。接口本身也具有数据成员与抽象方法,但它与抽象类有下列不同。
(1)接口的数据成员都是静态且必须初始化;
(2)接口中的方法必须全部都声明为abstract的,也就是说,,接口不像抽象类一样拥有一般的方法,而必须全部是抽象方法。
8.3.1 接口的定义
接口定义的语法如下:
[public] interface 接口名称 [extends 父接口名列表]
{
[public][static][final] 数据类型 成员变量名=常量;
.
.
.
[public][abstract] 返回值的数据类型 方法名(参数表);
.
.
.
}
其中interface前的public修饰符可以省略,若省略,接口使用默认的访问控制,即接口只能被与它处在同一包中的成员访问。当修饰符为public时,接口能被任何类的成员所访问。
接口与一般的类一样,本身也具有成员变狼与成员方法,但成员变量必须是静态的且一定要赋初值,而且此值不能被修改。若省略成员变量的修饰符,则系统默认为Public static final;其成员方法必须是抽象方法。
8.3.2 接口的实现与引用
既然接口只有抽象方法,它只需要声明而不用定义方法体,所以接口与抽象类一样不能用new运算符直接创建对象。相反地,必须利用接口的特性来建造一个新的类,然后再用它来创建对象。利用接口创建新类的过程称为接口的实现。接口的实现类似于继承,只是不用extends关键字,而是在声明一个类的同时用关键字implements来实现一个接口,接口实现的语法定义为:
class 类名称 implements 接口名表
{
.
.
.
}
一个类要实现一个接口时,应该注意以下问题:
(1)如果实现某接口的类不是不是abstract的抽象类,则在类的定义部分必须实现指定接口的所有抽象方法。即非抽象类中不能存在抽象方法;
(2)一个类在实现某接口的抽象方法时,必须使用完全相同的方法头。否则,只是在定义一个新方法,而不是实现已有的抽象方法;
(3)接口中抽象方法的访问控制修饰符都已指定为public,所以类在实现方法时,必须显式地使用public修饰符,否则将被系统i警告为缩小了接口中定义的方法的访问控制范围。
//filename: App8_11.java
interface IShape
{
final double PI=3.14;
abstract double getArea();
abstract double getLength();
}
class Circle implements IShape
{
double radius;
public Circle(double r)
{
radius=r;
}
public double getArea()
{
return PI*radius*radius;
}
public double getLength()
{
return 2*PI*radius;
}
}
class Rectangle implements IShape
{
private double width;
private double height;
public Rectangle(double width,double height)
{
this.width=width;
this.height=height;
}
public double getArea()
{
return width*height;
}
public double getLength()
{
return 2*(width+height);
}
}
public class App8_11
{
public static void main(String[] args)
{
IShape circle=new Circle(5.0);
System.out.print("The area of circle ="+circle.getArea());
System.out.print(";length= "+circle.getLength());
Rectangle rect=new Rectangle(6.5,10.8);
System.out.print("The ara of rectangle ="+rect.getArea());
System.out.print(";length="+rect.getLength());
}
}
8.3.3 接口的继承
于类相似,接口也有继承性。定义一个接口时可通过extends关键字声明该接口是某个已存在的父接口的子接口,它将继承父接口的所有变量 与方法。与类的继承不同的是,一个接口可以有一个以上的父接口,他们之间用逗号分隔,形成父接口列表。
8.3.4 利用接口实现类的多重继承
Java语言只支持类的单重继承机制,不支持类的多重继承,即一个类只能有一个直接的父类。单继承性使得Java程序结构简单、层次清楚、易于管理、更安全可靠,从而避免了C++中多重继承而引起的难以预测的冲突。
一个类只能有一个父类,但是它可以同时实现若干个接口。一个类实现多个接口时,在implements子句中用逗号分隔各个接口名。这种情况下把接口理解成特殊的类,那么这个类利用接口实际上就获得了多个父类,即实现了多重继承。
8.4 内部类与匿名内部类
内部类是定义在类中的类,内部类的主要作用是将逻辑上相关的类放到一起;而匿名内部类是一种特殊的 内部类,它没有类名,在定义类的同时,就生成该类的一个实例,由于不会在其他地方引用到类,所有不用取名字,因而被称为匿名内部类。
8.4.1 内部类
内部类是包含在类中的类,所以内部类也被称为嵌套类。包含内部类的类称为外部类。其实内部类可以看作外部类的一个成员,所以内部类也可以被称为成员类。与一般类相同,内部类可以拥有自己的成员变量与成员方法,通过建立内部类对象,i可以访问其成员变量或调用成员方法。
i定义内部类时只需将类的定义置于一个用于封装它的类的内部即可。但需要注意的是,内部类不能与外部类同名,否则编译器将无法识别内部类与外部类。如果内部类还有内部类,则内部类不能与他任何一层外部类同名。
在封装它的类的内部使用内部类,与使用普通类的方式相同,但在外部引用内部类的时候,则必须在内部类名前冠以七所属的外部类名字才能使用。在用new运算符创建内部类时,也要在new前面冠以对象变量。
Java将内部类作为一个成员,就如同成员变量和成员方法。
内部类具有以下特性:
内部类可以声明为private或protected;
内部类的前面可以用final修饰,则表明该内部类不能被继承;
内部类可以定义为abstract,但需要被其他的内部类继承或实现;
内部类不能与包含它的外部类名相同;
内部类既可以使用外部类的成员变量,包括静态变量和是成员变量,也可以使用内部类所在方法的局部变量;
内部类可以是一个接口,该接口必须由另一个类来实现;
内部类不但可以在类中定义,也可以在程序块之内定义内部类;
内部类如果被声明为static,则静态内部类将自动转化为顶层类。即它没有父类,而且不能引用到外部类成员或其他内部类中的成员。
8.4.2 匿名内部类
所谓匿名内部类,是指利用内部类创建没有名称的对象 ,它一步完成了声明内部类和创建该类的一个对象,并利用该对象访问到类里面的成员。格式如下:
//创建匿名内部类,并执行所定义的方法
new 类名() //括号()内不允许有参数
{
方法名(参数1,参数2,参数3,...,参数n)
{
方法体语句;
}
}
方法名(参数1,参数2,...,参数n);
创建匿名类的用意,主要是用来补充内部类中没有被定义到的方法,并可有效的简化程序代码。
//filename: App8_15.java
public class App8_15
{
public static void main(String[] args)
{
(
new Inner()
{
void setName(String n)
{
name=n;
System.out.println("name :"+name);
}
}
).setName("zhang hua");
}
static class Inner
{
String name;
}
}
8.5 包
利用面向对技术开发一个实际系统时,通常需要设计许多类共同工作,但由于Java编译器为每一个类生成一个字节码文件,同时,在Java语言中要求文件名与类名相同,因此若要将多个类放在一起,就要保证类名不能重复。但当声明很多类时,类名冲突的可能性很大,这时,就需要利用合理的机制来管理类名,引入包的概念来管理类名空间。就像用文件夹把各种文件组织在一起。
8.5.1 包的概念
所谓包,就是java语言提供的一种区别类名空间的机制,是类的组织方式,每个包对应一个文件夹,包中还可以有包,称为包等级。
在源程序中可以声明类所在的包,就像保存文件时要说明为念保存在哪个文件夹一样。同一包中的类名不能重复,不同包中的类名可以相同。所以说,包实际上提供了一种命名机制和可见性限制机制。
当源程序没有声明类所在的包时,Java将类放在默认包中,这意味着每个类使用的名字必须互不相同,否则会发生名字冲突,就像在一个文件夹中的文件名不能相同一样。一般不要求处于同一包中的类有明确的相互关系,如包含、继承等。但是由于同一包中的类在默认情况下可以相互访问,所以为了方便编程和管理,通常把需要在一起工作的类放在一个包中。
8.5.2 使用package语句创建包
若要建立自己的包,就必须以package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包。格式如下:
package 包名1[.包名2[.包名3]...];
经过package的声明之后,在同一文件内的所有类或接口都被纳入相同的包中。Java编译器把包视同于文件系统的文件夹来进行管理。用.来指明层次。
实际上,创建包就是在当前文件夹下创建一个子文件夹,以便于存放这个包中所含有的.class文件。语句中的.代表文件分隔符,即该语法创建了几个文件夹。
注:包名与与对应的文件夹名字母大小写应该一致。
包层次的根文件夹是由于环境变量ClassPath来确定的。在Java源文件中若没有使用package语句声明类所在的包,则Java默认包的路径是当前文件夹,并没有包名,即无名包。无名包不能有子包。
注:包及子包的定义,实际上是为了解决名字空间、名字冲突的问题,它与类的继承没有关系。事实上,一个子类与其父类可以位于不同 的包中。使用包名时要十分小心,如果要改变一个包名,旧必须同时改变对应的文件夹名。
8.5.3 Java语言中的常用包
由于java语言的package是用来存放类与接口的地方,所以也把package翻译为类库。即Java类库是以包的形式实现的,Java语言已经将功能相近的类分门别类地存放到不同类库中(除类之外还有接口、异常等)。Java提供的用于语言开发的类库,称为应用程序编程接口(API),分别放在不同的包中。Java语言常用包有:
java.lang 语言包
java.io 输入输出流的文件包
java.awt 抽象窗口工具包
javax.swing 轻型组件工具包
java.util 实用包
javax.swing.JApplet 小程序包
java.net 网络包
java.sql 数据库连接包
java.text 文本包
1.语言包
语言包提供了Java语言最基础的类。每个Java程序运行时,系统都自动地引入java.lang包,所以该包的加载是默认的。该包中主要包括如下类:
Object类
数据类型包装类
字符串类
数学类
系统和运行时类
类操作类
错误和异常处理类
线程类
过程类
2.输入和输出文件包
凡是需要完成与操作系统有关的较底层的输入输出操作的Java程序,都需要使用该包。该包中主要包含的类如下:
基本输入、输出流类
文件输入、输出流类
过滤输入、输出流类
管道输入、输出流类
随机输入、输出流类
3.抽象窗口工具包
抽象窗口工具包是用来构建图形用户界面的类库,他包括许多界面元素和资源。利用该包,开发人员可以很方便地写出美观、实用、标准化的应用程序界面。该包主要子啊三个方面提供界面设计支持;低级绘图操作,图形界面组件和布局管理、界面用户交互控制和事件相应。该包中所包含的 类如下:
绘图类
各种控件类
布局管理类
事件类
4.轻型组件工具包
轻型组件工具包的主要包含有:
数据输入类
日期类
链表类
向量类
哈希表类
栈类
树类
6.小程序包
小程序包用来实现运行于Internet浏览器中的Java Applet的工具类库,
7.网络功能包
网络功能包java.net是Java语言中用力啊实现网络功能的类库。由于Java语言在不断发展和扩充,它的功能尤其是网络功能也不断扩充。目前已经实现的网络功能有:底层的网络通信、访问internet资源。开发者可以利用Java.net包中的类,开发出具有网络功能的应用程序。该包中的主要包含的 类如下:
访问资源网络类
套接字类
服务端套接字类
数据报打包类
数据报通信类
8.数据库连接包
数据库连接包java.sql。利用该包可以使java程序工具拥有访问不同种类数据库的功能。只要安装了合适的驱动程序,同一个Java程序不需修改就可以访问这些不同数据库的功能。
9.文本包
java.中的java.text中的Format、DataFormat、SimpleDataFormat等提供各种文本或日期格式。
8.5.4 Java语言中几个常用的类
1.Data类
2.Calendar类
3.Random类
4.Math类
8.5.5 利用import语句引用Jav定义的包
1.导入包
如果要使用java包中的类,必须在源程序中用import语句导入所需要的类。import语句的格式为:
import 包名1 [.包名2[.包名3...]].类名 | *
其中import是关键字,包名1 [.包名2[.包名3...]]表示包的层次,与package语句相同,它对应于文件夹。”类名“则指明所要导入的类,如果从一个类库中导入多个类,则可以使用*表示包中的所有类。
Java编译器为所有程序自动隐含地导入java.lang包,因此用户无须用import导入它所包含的 所有类,就可使用其中的类,但是若要使用其他包中的类,旧必须使用import语句导入。
注:使用*表示本层次的所有类,不包括子层次中的类。
另外,凡在Java程序中需要使用类的地方,都可以指明包含该类的包。这样就不必用import语句引入类了。
2.Java包的路径
由于Java系统使用文件系统来存储包和类,类名就是文件名,包名就是文件夹名。若要引用Java包,仅在源程序中增加import语句是不够的,还必须告诉系统,程序运行时在哪儿才能找到Java的包。由于包层次的根文件夹是由环境变量ClassPath来确定的。所以这个功能由环境变量ClassPath完成。
8.5.6 Java程序结构
一个Java源文件一般可以包含以下部分:
package //声明包,0或1个
import //导入包,0或多个
public class //声明公有类,0或1个,文件名与该类名相同
class //声明类,0或多个
interface //声明接口,0或多个
其中,只能有一个声明包的语句,且必须是一条语句,声明为public的类最多只能有一个,文件名必须与该类名相同。
8.6 Java语言的垃圾回收
在Java程序的生命周期中,Java运行环境提供了一个系统的垃圾回收器线程,负责自动回收那些没有引用与之相连的对象所占用的内存,这种清除无用的对象 的进行内存回收的过程就叫做垃圾回收。垃圾回收是java语言提供的一种自动内存回收功能,可以让程序员减轻许多内存管理的负担,也减少程序员犯错的机会。
当一个对象被创建时,JVM为该对象分配一定的的内存、调用该对象的构造方法并开始跟踪对象。当对象停止使用时,JVM将通过垃圾回收器回收该对象所占用的内存。Java程序中有引用计数器。可以计算对象的引用次数。
垃圾回收有两个好处:
1)它把程序员从复杂的内存追踪、监测、释放等工作中解放出来
2)它防止了系统内存被非法释放,从而使系统更加稳定。
垃圾回收有以下特点:
只有当一个对象不被任何引用类型的变量使用时,它占用的内存才可能被垃圾回收器回收。
不能通过程序强迫垃圾回收器立即执行。
当垃圾回收期将要释放无用对象的内存时,先调用该对象的finalize()方法。
最后
以上就是娇气楼房为你收集整理的Java学习7——书本自学的全部内容,希望文章能够帮你解决Java学习7——书本自学所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复