温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Java中重复运用classes的方法是什么

发布时间:2022-01-07 20:24:07 来源:亿速云 阅读:113 作者:iii 栏目:编程语言

本篇内容主要讲解“Java中重复运用classes的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java中重复运用classes的方法是什么”吧!

一.继承(inheritance)

1.  在derived class中overriding某个函数时,只能覆写base class中的接口,即base class中的public或protected或friendly函数。如果试图overriding一个private函数,虽然编译通过,但实际上你只是在derived class中添加了一个函数。如

class Cleanser{   

  private void prt(){//(b)

  System.out.println("Cleanser.prt()");

  }

 }

public class ExplicitStatic extends Cleanser{

  public void prt(){

  System.out.println("ExplicitStatic.prt()");

  }

  public static void main(String[] args){

  Cleanser x = new ExplicitStatic();

  x.prt();//(a)

  }

}

因为Cleanser中的prt()是private,所以不能在其derived class中被覆写。ExplicitStatic中的prt()只是ExplicitStatic中的一个函数,所以当试图在(a)处通过多态来调用prt()时,会发生错误。如果把(b)处的private去掉,则结果为

ExplicitStatic.prt()

2.  Super的使用

1)通过关键字super可以调用当前class的superclass(父类)。

例6.1.1.1

class Base{

  Base(){System.out.println("Base()");}

  public void scrub() { System.out.println(" Base.scrub()"); }

}

class Cleanser extends Base{

  private String s = new String("Cleanser");

  public void append(String a) { s+=a; }

  public void dilute() { append(" dilute()"); }

  public void apply() { append(" apply()"); }

  public void scrub() { append(" scrub()"); }

  public void print() { System.out.println(s); }

  Cleanser(){

  System.out.println("Cleanser(): " + s);

  }

  public static void testStatic(){

  System.out.println("testStatic()");

  }

  public static void main(String[] args){

  Cleanser x = new Cleanser();

  x.dilute(); x.apply(); x.scrub(); x.print();

  }

 }

public class ExplicitStatic extends Cleanser{

  ExplicitStatic(){

  System.out.println("ExplicitStatic()");

  }

  public void scrub(){

  append(" Detergen.scrub()");

  super.testStatic();

  super.scrub();//调用的是Cleanser.scrub()

  }

  public void foam() { append(" foam()"); }

  public static void main(String[] args){

  ExplicitStatic x = new ExplicitStatic();

  x.dilute(); x.apply(); x.scrub(); x.foam();

  x.print(); System.out.println("Test base class:");

  Cleanser.main(args); 

  testStatic();

  }

}

运行结果:

Base()

Cleanser(): Cleanser

ExplicitStatic()

testStatic()

Cleanser dilute() apply() Detergen.scrub() scrub() foam()

Test base class:

Base()

Cleanser(): Cleanser

Cleanser dilute() apply() scrub()

testStatic()

2)通过super来调用superclass中的成员时,调用的是最近成员。

例6.1.1.2

class Base{

  protected String baseS = "Base";//(a)

  //private String baseS = "Base";

  Base(){System.out.println("Base()");}

}

class Cleanser extends Base{

  protected String baseS = "Cleanser";//(b)

  public String s = new String("Cleanser");

  Cleanser(){

  System.out.println("Cleanser(): " + s);

  }

  Cleanser(String a){

  System.out.println("Cleanser(" + a + "): s = " + s );

  }

 }

public class ExplicitStatic extends Cleanser{

  String s2 = s;

  String baseS = super.baseS; //(c)

  ExplicitStatic(){

  super("ExplicitStatic");

  System.out.println("ExplicitStatic():s2 = " + s2 + ", baseS = " + baseS + "super.baseS = " + super.baseS);

  baseS = "ExplicitStatic";

  System.out.println("baseS = " + baseS + " , super.baseS = " + super.baseS);

  }

  public static void main(String[] args){

  ExplicitStatic x = new ExplicitStatic();

  }

}

结果1:

Base()

Cleanser(ExplicitStatic): s = Cleanser

ExplicitStatic():s2 = Cleanser, baseS = Cleanser,super.baseS = Cleanser

baseS = ExplicitStatic , super.baseS = Cleanser

在上面例子中,在三个class中都存在String bases实例。在ExplicitStatic中如果直接调用baseS,则实际调用的是当前类ExplicitStatic中的baseS(即(c)处的成员);如果通过super.bases来调用baseS,则调用的是离当前类ExplicitStatic最近的baseS成员,即Cleanser class中的baseS实例(即(b)处),产生的结果如结果1所示。如果把(b)处语句注释掉,则将调用Base class中的baseS,结果如结果2所示。

结果2:

Base()

Cleanser(ExplicitStatic): s = Cleanser

ExplicitStatic():s2 = Cleanser, baseS = Base,super.baseS = Base

baseS = ExplicitStatic , super.baseS = Base

3.  Base class的初始化

2.1  当你产生derived class对象时,其中会包含base class子对象(subobject)。这个子对象就和你另外产生的base class对象一模一样。

2.2  通过super()可调用base class的构造函数,但必须放在构造函数的第一行,并且只能在构造函数中运用。

2.3  初始化顺序为:

1)  加载代码(.class文件)

2)  初始化class的静态成员,初始化顺序了“从里到外”,即从base class开始。

3)  在derived class的构造函数中调用base class的构造函数。

如果在derived class的构造函数中没有通过super()显式调用调用base class的构造函数,编译器会调用bass class的default构造函数并自动生成相应的调用语句,从而产生一个base class实例。如果在derived class的构造函数中通过super()显示调用了父类的构造函数,则调用所指定的构造函数。调用构造函数的调用顺序是“从里到外”。

4)  调用derived class的构造函数。

**:当base class没有default构造函数时,必须在derived class的构造函数中通过super显示调用base class的构造函数。

例:下面代码的初始化过程为:

1)  装载ExplicitStatic的代码(装载ExplicitStatic.class文件)。

2)  发现ExplicitStatic有关键字extends,装载ExplicitStatic的base class的代码(装载Cleanser.class文件)。

3)  发现Cleanser有关键字extends,装载Cleanser的base class的代码(装载Base.class文件)。

4)  初始化Base class中的静态成员。

5)  初始化Cleanser class中的静态成员。

6)  初始化ExplicitStatic class中的静态成员。

如果把(c)处的代码注释掉,那么初始化工作到此就结束了。

7)  为ExplicitStatic对象分配存储空间,并把存储空间初始化为0。

8)  在ExplicitStatic class的构造中调用super("ExplicitStatic")(在ExplicitStatic class的构造函数中显式调用父类的构造函数),试图产生一个Cleanser class实例。

9)  为Cleanser对象分配存储空间,并把存储空间初始化为0。

10)  由于Cleanser class又是继承自Base class,会在Cleanser class的构造函数中通过super()(由于没有显式调用父类的构造函数,所以自动调用父类的default构造函数)调用父类的构造函数,试图产生一个Cleanser class实例。

11)  产生一个Base class实例。先初始化成员变量,再调用构造函数。

12)  回到Cleanser class,产生一个实例。首先初始化Cleanser class中的成员数据,再执行构造函数Cleanser(String a)中的其余部分。

13)  回到ExplicitStatic class,产生一个实例。首先初始化ExplicitStatic class中的成员数据,再执行构造函数ExplicitStatic ()中的其余部分(System.out.println(“ExplicitStatic()”))。

class Base{

  static int s1 = prt("s1 initialized.", 11);

  int i1 = prt("i1 initialized.", 12);

  Base(){

  System.out.println("Base()");

  System.out.println("s1 = " + s1 + " ,i1 = " + i1);

  draw();//(d)

  }

  void draw(){

  System.out.println("base.draw:s1 = " + s1 + " ,i1 = " + i1);

  }

  static int prt(String s, int num) {

  System.out.println(s);

  return num;

  }

}

class Cleanser extends Base{

  static int s2 = prt("s2 initialized.", 21);

  int i2 = prt("i2 initialized.", 22);

  Cleanser(){

   System.out.println("Cleanser()");

  System.out.println("s2 = " + s2 + " ,i2 = " + i2);

  }

  Cleanser(String a){

  //super();(b)

  System.out.println("Cleanser(" + a + ")");

  System.out.println("s2 = " + s2 + " ,i2 = " + i2);

  }

  void draw(){

  System.out.println("Cleanser.draw:s2 = " + s2 + " ,i2 = " + i2);

  }

 }

public class ExplicitStatic extends Cleanser{

  static int s3 = prt("s3 initialized.", 31);

  int i3 = prt("i3 initialized", 31);

  ExplicitStatic(){

  super("ExplicitStatic");//(a)

  System.out.println("ExplicitStatic()");

  System.out.println("s3 = " + s3 + " ,i3 = " + i3);

  }

  public static void main(String[] args){

  ExplicitStatic x = new ExplicitStatic();//(c)

  }

}

结果:

s1 initialized.

s2 initialized.

s3 initialized.

//如果把(c)处的代码注释掉,输出结果到此为止,不会输出下面结果

i1 initialized.

Base()

s1 = 11 ,i1 = 12

Cleanser.draw:s2 = 21 ,i2 = 0//(d)处结果

i2 initialized.

Cleanser(ExplicitStatic)//(a)处结果

s2 = 21 ,i2 = 22

i3 initialized

ExplicitStatic()

s3 = 31 ,i3 = 31

由于在Base()中调用draw()时,Cleanser中的i2还未进行初始化,而在为Cleanser对象分配存储空间时,把存储空间初始化为0,所以此时i2为0。

2.4  代码及结果中的(a)说明了是先产生当前class的base class的实例,否则在derived class中无法调用base class的成员。在调用Cleanser class的构造函数Cleanser(String a)时,在Cleanser(String a)中没有用super显式调用Base class的构造函数,所以系统会自动生成调用Base class的default构造函数的语句,如(b)。

4.  组合与继承之间的快择

.  1)继承表示的是一种“is-a(是一个)”的关系,如货车是汽车中的一种;组合表示的是一种“has-a(有一个)”的关系,如汽车有四个轮子。

  2)是否需要将新的class向上转型为base class。

5.  在继承中的访问权限

protect变量能被子孙类所调用。如Base class中的baseS能被Cleanser class和ExplicitStatic class调用。

class Base{

  protected String baseS = "Base";

  //private String baseS = "Base";

  Base(){System.out.println("Base()");}

}

class Cleanser extends Base{

  protected String baseS = "Cleanser";

  public String s = new String("Cleanser");

  Cleanser(){

  System.out.println("Cleanser(): " + s);

  }

  Cleanser(String a){

  System.out.println("Cleanser(" + a + "): s = " + s );

  }

 }

public class ExplicitStatic extends Cleanser{

  String s2 = s;

  String baseS = super.baseS;

  ExplicitStatic(){

  super("ExplicitStatic");

  System.out.println("ExplicitStatic():s2 = " + s2 + ", baseS = " + baseS + "super.baseS = " + super.baseS);

  baseS = "ExplicitStatic";

  System.out.println("baseS = " + baseS + " , super.baseS = " + super.baseS);

  }

  public static void main(String[] args){

  ExplicitStatic x = new ExplicitStatic();

  }

}

结果:

Base()

Cleanser(ExplicitStatic): s = Cleanser

ExplicitStatic():s2 = Cleanser, baseS = Cleanser, super.baseS = Cleanser

baseS = ExplicitStatic , super.baseS = Cleanser

二.关键字final

1.Final data

  1.1 final data

1)当基本型别被定义为final,表示它的数据值不能被改变。如

  final int i = 9;

  i++;//编译错误,不能改变I的值

2) 当object reference被定义为final时,不能改变的只是reference而不是对象本身。如

  class Value{ 

    int i = 1;

  }

public class ExplicitStatic extends Cleanser{

    public static void main(String[] args){

    final Value v = new Value();//v.i = 1

    v.i++;//v.i = 2

    //v = new Value();

    }

}

由于v为final,所以不能通过new Value()使v重新指向一个对象;但是v所指向的对象的值是可以改变的(v.i++)。

1.2 blank finals

我们可以将数据成员声明为final但不给予初值,这就是blank finals。但blank finals必须且只能在构造函数中进行初始化。

  public class ExplicitStatic {

  final int ib;

  final int i = 1;

  ExplicitStatic()

  {

  ib = 2;//(a)

  //i = 3; (b)

  System.out.println("i = " + i  + ", ib = " + ib);

  }

  public static void main(String[] args){

  ExplicitStatic ex = new ExplicitStatic();

  }

}

ib为blank finals,所以可以在构造函数中进行初始化。如果把(a)处的代码注释掉,则ib没有初值,编译出错。而i在定义处已进行了初始化,则不能改变i的值,(b)处的代码编译错误。

**:非blank finals成员即使在构造函数中也不能更改其值

2.Final methods

  1)被声明为final的函数不能被覆写

  2)class中所有private函数自然而然会是final。

1.  Final classes

1)当一个class被声明为final时,表示它不能被继承,但class的数据成员不是final,可以被改变。如

  class SmallBrain{}

 XML:namespace prefix = o ns = "urn:schemas-microsoft-com:Office:office" />

final class Dinosaur{

    int i = 7;

    int j = i;

    SmallBrain x = new SmallBrain();

    void f(){};

}

//不能继承final函数

//class Further extends Dinosaur{}

public class ExplicitStatic{

    public static void main(String[] args){

    Dinosaur n = new Dinosaur();

    n.f();

    n.i = 40;//final class中的non-final数据成员可以被改变

      n.j++;

    }

}

2)final class中的所有函数也都自然是final,因为没有人能够加以覆写。

到此,相信大家对“Java中重复运用classes的方法是什么”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI