第一个盒子,定义一个盒子类,当编译该程序时,将会发现创建两个.class文件,一个是上面的盒子类,一个是下面的盒子类.java编译器自动将每个类放入到各自的.class文件中.并且非常严格将盒子1与Spurs_ping盒子1放入同一个源文件中,可以将它们分别放置在自己文件中命名为Box1.java与Spurs_pingBox1.java,运行此代码必须在终端执行Spurs_ping.java
package new_world1;
class Box1{
double width;
double height;
double depth;
}
public class Spurs_ping36Box1 {
public static void main(String[] args) {
Box1 mybox=new Box1();
double vol;
mybox.width=10;
mybox.height=20;
mybox.depth=15;
vol=mybox.width*mybox.height*mybox.depth;
System.out.println("Volume is "+vol);
}
}
运行结果:
Volume is 3000.0
第二个盒子,尽管创建只包含数据的类完全没问题,但是很少遇到这种情况.大多数情况下会使用方法访问由类定义的实例变量.除了访问数据的方法之外还可以定义在内部由类自己使用的方法.为此,需要为Box类添加一个方法:
package new_world1;
class Box2{
double width;
double height;
double depth;
}
public class Spurs_ping37Box2 {
public static void main(String[] args) {
Box2 mybox1=new Box2();
Box2 mybox2=new Box2();
double vol;
mybox1.width=10;
mybox1.height=20;
mybox1.depth=15;
mybox2.width=3;
mybox2.height=6;
mybox2.depth=9;
vol=mybox1.width*mybox1.height*mybox1.depth;
System.out.println("Volumn is "+vol);
vol=mybox2.width*mybox2.height*mybox2.depth;
System.out.println("Volumn is "+vol);
}
}
运行结果:
Volumn is 3000.0
Volumn is 162.0
第三个盒子,虽然volume()方法的实现确实将箱子体积计算转移到了包涵该方法的盒子类内部,但这并不是完成该任务的最好方式.例如如果程序的另一部分需要知道箱子的体积,而不是显示体积的值,该怎么办?使用volume()方法的更好方式是,用该方法计算箱子体积并且向调用者返回计算结果,如下是第二个盒子的加强版:
package new_world1;
class Box3{
double width;
double height;
double depth;
void volume(){
System.out.print("Volume is ");
System.out.println(width*height*depth);
}
}
public class Spurs_ping38Box3 {
public static void main(String[] args) {
Box3 mybox1=new Box3();
Box3 mybox2=new Box3();
mybox1.width=10;
mybox1.height=20;
mybox1.depth=15;
mybox2.width=3;
mybox2.height=6;
mybox2.depth=9;
mybox1.volume();
mybox2.volume();
}
}
结果:
Volume is 3000.0
Volume is 162.0
第五个盒子是添加返回值:
package new_world1;
class Box5{
double width;
double height;
double depth;
double volume() {
return width*height*depth;
}
}
public class Spurs_ping39Box5 {
public static void main(String[] args) {
Box5 mybox1=new Box5();
Box5 mybox2=new Box5();
double vol;
mybox1.width=10;
mybox1.height=20;
mybox1.depth=15;
mybox2.width=3;
mybox2.height=6;
mybox2.depth=9;
vol=mybox1.volume();
System.out.println("Volume is "+vol);
vol=mybox2.volume();
System.out.println("Volume is "+vol);
}
}
结果:
Volume is 3000.0
Volume is 162.0
可以看出带返回值的就是方便的多,虽然对于我们来说并没有什么区别,但对于JVM来说还是要舒服的多.当调用volume()时,将其放到赋值语句的右侧,左侧是变量,对于这个例子该变量将接收由volume()方法返回的值.
第六个盒子是添加参数的方法,虽然有些方法不需要参数,但是大多数方法都带有参数. 参数可以使方法更加通用,也就是说到参数的方法可以对各种数据进行操作,以及可以用许多稍微又些差别的情况:
package new_world1;
class Box6{
double width;
double height;
double depth;
double volume() {
return width*height*depth;
}
void setDim(double w,double h,double d) {
width=w;
height=h;
depth=d;
}
}
public class Spurs_ping40Box6 {
public static void main(String[] args) {
Box6 mybox1=new Box6();
Box6 mybox2=new Box6();
double vol;
mybox1.setDim(10, 20, 15);
mybox2.setDim(3, 6, 9);
vol=mybox1.volume();
System.out.println("Volume is "+vol);
vol=mybox2.volume();
System.out.println("Volume is "+vol);
}
}
结果:
Volume is 3000.0
Volume is 162.0
可以看出,setDim()方法用于设置每个箱子的尺寸.
第七个盒子添加了构造函数(就是和类名相同没有返回值的函数,虽然没有返回值但是可以为对象添加属性):
package new_world1;
class Box7{
double width;
double height;
double depth;
Box7(){
System.out.println("Constructing Box");
width=10;
height=10;
depth=10;
}
double volume() {
return width*height*depth;
}
}
public class Spurs_ping41Box7 {
public static void main(String[] args) {
Box7 mybox1=new Box7();
Box7 mybox2=new Box7();
double vol;
vol=mybox1.volume();
System.out.println("Volume is "+vol);
vol=mybox2.volume();
System.out.println("Volume is "+vol);
}
}
结果:
Constructing Box
Constructing Box
Volume is 1000.0
Volume is 1000.0
new Box()是调用Box7()的构造函数,如果没有显示地为类定义构造函数,java就会为类创建默认的构造函数这就是为什么上面的代码,在没有定义构造函数能够工作的原因.默认的构造函数自动地将所有实例变量初始化为其默认值,对于数值类型引用类型和布尔类型这个默认值分别是0,null,false.对于简单的类默认构造函数通常是够用的,但是对于复杂的类,默认构造函数通常不能满足需要.一旦定义自己的构造函数,就不再使用默认的构造函数.
第八个盒子是参数化构造函数:
package new_world1;
class Box8{
double width;
double height;
double depth;
Box8(double w,double h,double d){
width=w;
height=h;
depth=d;
}
double volume() {
return width*height*depth;
}
}
public class Spurs_ping43Box8 {
public static void main(String[] args) {
Box8 mybox1=new Box8(10,20,15);
Box8 mybox2=new Box8(3,6,9);
double vol;
vol=mybox1.volume();
System.out.println("Volume is "+vol);
vol=mybox2.volume();
System.out.println("Volume is "+vol);
}
}
结果:
Volume is 3000.0
Volume is 162.0
当new运算符创建对象时,将数值10,20,15传递给box()的构造函数.因此mybox1的width,height,以及 depth副本将包含数值10,20,15.
第九个盒子演示了重载构造函数:
package new_world1;
class Box9{
double width;
double height;
double depth;
Box9(double w,double h,double d){
width=w; height=h; depth=d;
}
Box9(){
width=-1; height=-1; depth=-1;
}
Box9(double len){
width=height=depth=len;
}
double volume() {
return width*height*depth;
}
}
public class Spurs_ping46Box9 {
public static void main(String[] args) {
Box9 mybox1=new Box9(10,20,15);
Box9 mybox2=new Box9();
Box9 mybox3=new Box9(7);
double vol;
vol=mybox1.volume();
System.out.println("Volume of mybox1 is "+vol);
vol=mybox2.volume();
System.out.println("Volume of mybox2 is "+vol);
vol=mybox3.volume();
System.out.println("Volume of mybox3 is "+vol);
}
}
结果:
Volume of mybox1 is 3000.0
Volume of mybox2 is -1.0
Volume of mybox3 is 343.0
可以看出,当执行new运算符时,会根据制定的参数调用正确的重载构造函数.
第十个盒子将对象用作参数
package new_world1;
class Box10{
double width;
double height;
double depth;
Box10(Box10 ob){
width=ob.width;height=ob.height;depth=ob.depth;
}
Box10(double w,double h,double d){
width=w;height=h;depth=d;
}
Box10(){
width=-1;height=-1;depth=-1;
}
Box10(double len){
width=height=depth=len;
}
double volume() {
return width*height*depth;
}
}
public class Spurs_ping48Box10 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Box10 mybox1=new Box10(10,20,15);
Box10 mybox2=new Box10();
Box10 mycube=new Box10(7);
Box10 myclone=new Box10(mybox1);
double vol;
vol=mybox1.volume();
System.out.println("Volume of mybox1:"+vol);
vol=mybox2.volume();
System.out.println("Volume of mybox2:"+vol);
vol=mycube.volume();
System.out.println("Volume of mycube:"+vol);
vol=myclone.volume();
System.out.println("Volume of mycolne:"+vol);
}
}
结果:
Volume of mybox1:3000.0
Volume of mybox2:-1.0
Volume of mycube:343.0
Volume of mycolne:3000.0
当开始创建自己的类时,为了能够以方便的并且高效的方式构造对象,通常需要提供多种形式的构造函数.
第十一个盒子演示了继承的一部分:
package new_world1;
class Box11{
double width;double height;double depth;
Box11(Box11 ob){
width=ob.width;height=ob.height;depth=ob.depth;
}
Box11(double w,double h,double d){
width=w;height=h;depth=d;
}
Box11(){
width=-1;height=-1;depth=-1;
}
Box11(double len){
width=height=depth=len;
}
double volume() {
return width*height*depth;
}
}
class BoxWeight extends Box11{
double weight;
BoxWeight(double w,double h,double d,double m){
width=w;height=h;depth=d;weight=m;
}
}
public class Spurs_ping66Box11 {
public static void main(String[] args) {
// TODO Auto-generated method stub
BoxWeight mybox1=new BoxWeight(10,20,15,34.3);
BoxWeight mybox2=new BoxWeight(2,3,4,0.076);
double vol;
vol=mybox1.volume();
System.out.println("Volume of mybox1 is"+vol);
System.out.println("Weight od mybox1 is"+mybox1.weight);
System.out.println();
vol=mybox2.volume();
System.out.println("Volume of mybox2 is"+vol);
System.out.println("Weight of mybox2 is"+mybox2.weight);
}
}
结果:
Volume of mybox1 is3000.0
Weight od mybox1 is34.3
Volume of mybox2 is24.0
Weight of mybox2 is0.076
BoxWeight继承了Box类的所有特征,并且添加了weight的元素没有必要为BoxWight重新创建盒子的所有特征,可以简单地扩展Box类以满足自己的目的.一旦创建一个定义对象通用方面的超类,就可以继承这个超类,形成更为特殊的子类,每个字类再简单滴增加自己特有的属性.这就是继承的本质.
第十二个盒子使用super关键字调用超类的构造函数
package new_world1;
class Box12{
private double width;
private double height;
private double depth;
Box12(Box12 ob){
width=ob.width;height=ob.height;depth=ob.depth;
}
Box12(double w,double h,double d){
width=w;height=h;depth=d;
}
Box12(){
width=-1;height=-1;depth=-1;
}
Box12(double len){
width=height=depth=len;
}
double volume() {
return width*height*depth;
}
}
class BoxWeight6 extends Box12{
double weight;
BoxWeight6(BoxWeight6 ob){
super(ob);
weight=ob.weight;
}
BoxWeight6(double w,double h,double d,double m){
super(w,h,d);
weight=w;
}
BoxWeight6(){
super();
weight=-1;
}
BoxWeight6(double len,double m){
super(len);
weight=m;
}
}
public class Spurs_ping67Box12 {
public static void main(String[] args) {
// TODO Auto-generated method stub
BoxWeight6 mybox1=new BoxWeight6(10,20,15,34.3);
BoxWeight6 mybox2=new BoxWeight6(2,3,4,0.076);
BoxWeight6 mybox3=new BoxWeight6();
BoxWeight6 mycube=new BoxWeight6(3,2);
BoxWeight6 myclone=new BoxWeight6(mybox1);
double vol;
vol=mybox1.volume();
System.out.println("Volume of mybox1 is"+vol);
System.out.println("Weight of mybox1 is"+mybox1.weight);
System.out.println();
vol=mybox2.volume();
System.out.println("Volume of mybox2 is"+vol);
System.out.println("Weight of mybox2 is"+mybox2.weight);
System.out.println();
vol=mybox3.volume();
System.out.println("Volume of mybox3 is"+vol);
System.out.println("Weight of mybox3 is"+mybox3.weight);
System.out.println();
vol=myclone.volume();
System.out.println("Volume of myclone is"+vol);
System.out.println("Weight of mycolne is"+myclone.weight);
System.out.println();
vol=mycube.volume();
System.out.println("Volume of mycube is"+vol);
System.out.println("Weight of mycube is"+mycube.weight);
System.out.println();
}
}
结果:
Volume of mybox1 is3000.0
Weight of mybox1 is10.0
Volume of mybox2 is24.0
Weight of mybox2 is2.0
Volume of mybox3 is-1.0
Weight of mybox3 is-1.0
Volume of myclone is3000.0
Weight of mycolne is10.0
Volume of mycube is27.0
Weight of mycube is2.0
值得注意的是,super()传递的是BoxWeight类型的对象,而不是Box类型的对象,这仍然会调用Box(Box ob)构造函数,可以使用超类变量引用继承自超类的任何对象.因此,可以为Box构造函数传递BoxWeight对象,当然,Box类只知道自己的成员.当子类调用super()时,会调用直接超类的构造函数,因此,super()总是饮用调用类的直接超类, 即在多层次继承中也是如此,此外,super必须总是字类构造函数的第一条语句.
最后一个盒子,创建多级继承层次:
package new_world1;
class Box13{
private double width;
private double height;
private double depth;
Box13(Box13 ob){
width=ob.width;height=ob.height;depth=ob.depth;
}
Box13(double w,double h,double d){
width=w;height=h;depth=d;
}
Box13(){
width=-1;height=-1;depth=-1;
}
Box13(double len){
width=height=depth=len;
}
double volume() {
return width*height*depth;
}
}
class BoxWeight16 extends Box13{
double weight;
BoxWeight16(BoxWeight16 ob){
super(ob);
weight=ob.weight;
}
BoxWeight16(double w,double h,double d,double m){
super(w,h,d);
weight=m;
}
BoxWeight16(){
super();
weight=-1;
}
BoxWeight16(double len,double m){
super(len);
weight=m;
}
}
class Shipment extends BoxWeight16{
double cost;
Shipment(Shipment ob){
super(ob);
cost=ob.cost;
}
Shipment(double w,double h,double d,double m,double c){
super(w,h,d,m);
cost=c;
}
Shipment(){
super();
cost=-1;
}
Shipment(double len,double m,double c){
super(len,m);
cost=c;
}
}
public class Spurs_ping69Box13 {
public static void main(String[] args) {
Shipment shipment1=new Shipment(10,20,15,10,3.41);
Shipment shipment2=new Shipment(2,3,4,0.76,1.28);
double vol;
vol=shipment1.volume();
System.out.println("Bolume of shipment1 is"+vol);
System.out.println("Weight of shipment1 is"+shipment1.weight);
System.out.println("Shipping cost:$"+shipment1.cost);
System.out.println();
vol=shipment2.volume();
System.out.println("Volume fo shipment2 is"+vol);
System.out.println("Weight of shipment2 is"+shipment2.weight);
System.out.println("Shipping cost:$"+shipment2.cost);
}
}
结果:
Bolume of shipment1 is3000.0
Weight of shipment1 is10.0
Shipping cost:$3.41
Volume fo shipment2 is24.0
Weight of shipment2 is0.76
Shipping cost:$1.28
因为使用了继承,所以Shipment类能够利用以前定义的Box和BoxWeight类,只需要添加自己的特定的应用程序所需的额外信息即可,这就是继承的价值允许重用代码,而且,super()总是引用最近超类的构造函数Shipment类中的super()调用BoxWeight类的构造函数.BoxWeight类中的super()调用Box类的构造函数,在类的层次中,如果超类的构造函数需要参数,那么所有字类必须向上传递这些参数.不管字类本身是否需要参数,都需要这么做.
最后:java作为继承封装多态的三大性质的编程语言与cpp有着异曲同工之妙,但他们的共同点就是花样非常多,变化也极其复杂,初学者千万要挺住,研究的多了感觉自然就来了.