Java学习7——书本自学

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()方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王辞夜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值