您的位置:首页 > 职场人生

黑马程序员—继承多态以及内部类

2014-01-28 14:50 246 查看
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! -----------------------

一、继承

1、继承的基本概念

把类中共性的内容抽取出来。必须类与类之间有所属关系才能继承。

提高代码的复用性,让类与类之间产生了关系,有了这个关系,才有了多态的特性。

Java语言不支持多继承是因为多继承会带来安全隐患。因为当多个父类中出现相同功能但内容不同的时候,子类对象不知道运行哪一个。但java用另外一个种形式表示多继承,就是多实现接口。java还支持多层继承,也就是一个继承体系。

2、怎样使用继承体系中的功能?

我们可以查阅父类的功能,因为父类中定义的是共性功能。通过父类就可以知道该体系的基本功能。不过具体调用的时候,要建立最子类的对象。因为有可能父类不能创建对象,还有就是创建子类对象可以使用更多的功能,包括基本的还有它自己特有的。

3、super 关键字

如果子类中出现非私有的成员变量时候,子类要访问本类中的变量,用this,子类要访问父类的同名变量,用super。super代表的是父类的引用。

4、重写

当子类中出现和父类同名的函数时候。子类对象调用该函数,会运行子类函数的内容,如同父类的函数被覆盖一样,这就是重写。也就是说保留父类的功能定义,并重写功能定义。

 注意点:子类覆盖父类的时候要保证子类的权限大于等于父类的权限。

  静态只能覆盖静态。

重写与重载的区别。

重载是只看同名函数的参数列表。

重写是字父类方法要一模一样。

5、子父类中的构造函数

在对子类对象进行初始化的时候,父类的构造函数也会运行,那是因为子类的构造函数的第一行都有一条隐式的super();这样就可以可以访问父类的空参数构造函数。而且子类中所有的构造函数第一行都是默认的super()。

子类一定要访问父类的构造函数。如果父类中没有空参数的构造函数。这时候super()就不能隐式存在。而是要自定义super()引用父类的构造函数。

注意:super语句只能定义在子类构造函数的第一行。构造函数中只能有this跟super中的一个。

结论:子类的所有构造函数默认都会访问父类中空参数的构造函数,因为每一个子类的构造函数内第一行都有一句隐式的super(),当父类中没有空参数的构造函数时,子类必须手动通过super或者this语句来访问父类中的构造函数。子类中至少有一个构造函数会访问父类中的构造函数。

 

6、final关键字

1、是一个修饰符,可以修饰变量,函数,类。

2、被final修饰的类不能被继承

3、被final修饰的方法不能被复写。

4、被final修饰的变量是一个常量,只能被赋值一次。既可以修饰成员变量,也可以修饰局部变量。

class fu
{
final int  x=3;
fu()
{
System.out.println("fu run");

}
fu(int x)
{
System.out.println(x+".....fu run");
}
final void show()//被final修饰的方法不可以被复写
{
System.out.println("......final");
}
}
class zi extends fu
{
zi()
{
super(4);//访问父类中的指定构造函数。
System.out.println("zi  run  ");
}
zi(int x)
{
super(4);
super.show();//调用父类中的show方法
//this();
//super();//隐式存在的。有this就不能有super();
System.out.println(x+"..zi run");
}
/*void show()
{
不能复写父类的被final修饰的 show方法
}*/
}
public class extendDemo
{
public static void main(String[] args)
{
//new zi();
new zi(4);
}
}

7、抽象类

1、用abstract 关键字修饰。抽象方法只能存在在抽象类中。抽象类不能用new建立对象。因为调用抽象方法没有意义。抽象类的方法要被使用必须由子类复写其所有的抽象方法后建立子类对象调用。如果子类只有覆盖部分的抽象方法,那么该子类还是个抽象类。

2、抽象类跟一般类没有太大的不同,该如何描述事物就怎么描述事物。只是把不确定的部分抽象化。抽象类不能被实例化。

3、模板设计模式:

在定义功能时候,功能的一部分是确定的,但是有一部分是不确定的。而确定的部分在使用不确定的部分,那么就把不确定的方法暴露出去,留给其子类去实现。

abstract class getSubTime
{
public final void getTime()
{
long start=System.currentTimeMillis();
run();//确定部分要调用不确定部分
long end=System.currentTimeMillis();
System.out.println("time="+(end-start));
}
public abstract void run(); //把不确定的方法暴露出去
}
class subTime extends getSubTime
{
public void run()//子类实现run方法
{
for(int x=0;x<100;x++)
{
System.out.println(x);
}

}
}
public class abstractDemo
{
public static void main(String[] args)
{
new subTime().getTime();
}
  }

8、接口

1、如果该类中的所有方法都是抽象的,那么该类就可以通过接口形式表现。接口是不可以实例化的,只有子类实现了它,对所有的抽象方法都覆盖后,子类才可以实例化。

2、接口中的成员都有固定修饰符:

常量:public static final

方法:public abstract

记住:接口中的成员都是public的。

3、接口可以被类多实现,这就是java支持多实现。接口之间也是可以有继承关系的。

interface Inter
  {
  	public  static  final int NUM=4;//定义常量
  	public abstract void show();
  }
  interface Inter1
  {
  	public abstract void show2();
  }
  class InterDemo implements Inter,Inter1
  {
  	public  void show()
  	{
  		System.out.println("实现接口Inter");
  	}
  	public  void
4000
show2()
  	{
  		System.out.println("实现接口Inter1");
  	}
  }

二、多态

1、多态的体现

父类的引用指向了自己的子类对象。父类的引用也可以接收自己的子类对象。

2、多态的前提

必须是类与类之间有关系,不是继承就是实现。还要有存在覆盖。

3、多态的好处

提高代码的扩展性.,但是有个局限性就是只能使用父类的引用使用父类中的方法

4、多态的应用

多态自始至终都是子类对象在做着变换。我们能转换的是父类引用指向子类对象时候,该应用可以被提升,也可以被强制转换。

注意:在多态中非静态成员函数的特点

编译时期:参阅引用变量所属的类是否有调用的方法,没有的话编译失败

运行时期:参阅对象所属的类中是否有调用的方法,有的话就运行对象类的方法,没有的话就运行父类的方法。

 

在多态中成员变量和静态成员函数的特点:无论编译还是运行时期都参阅的是引用变量所属的类。

 

  abstract class student
  {
  	abstract void  study();
  	void sleep()
  	{
  		System.out.println("躺着睡觉");
  	}
  }
  class yure extends student
  {
  	void study()
  	{
  		System.out.println("基础学习");
  	}
  
  	void sleep()
  	{
  		System.out.println("pa着睡觉");
  	}
  }
  
  class gaoji extends student
  {
  	void study()
  	{
  		System.out.println("冲刺学习");
  	}
  
  
  }
  class dosam
  {
  	void dosome(student stu)
  	{
  		stu.study();
  		stu.sleep();
  	}
  }
  class Duotai2
  {
  	public static void main(String[] args)
  	{
  		dosam a=new dosam();
  		a.dosome(new  yure());//student stu=new yure();
  		a.dosome(new gaoji());
  
  	}
  
  }

三、内部类

1、把一个类定义在类的内部就是内部类。使用内部类可以降低Java类命名的混乱,Java 中内部类可以分为成员内部类,局部内部类,静态内部类以及匿名内部类四种。下面就通过一些例子来介绍这几种内部类。

内部类的共性:

1、内部类可以直接访问外部类的成员(变量或者方法),包括私有,因为内部类持有一个外部类的引用,格式为   外部类名.this.成员

2、内部类 的访问规则:

外部类要访问内部类要先建立内部类的对象

一、成员内部类

当内部类作为外部类的成员存在,格式如下:

  class outer A
  {
  class inner b
  {
  
  }
  }

下面就是一个成员内部类的一个实例:

class outer
{
private int x=3;
class inner
{
int x=4;
void show()
{
int x=5;
System.out.println(outer.this.x);//内部类引用外部类成员的格式
}

}
void fun()
{
inner in = new inner(); //外部类方法要访问内部类首先要建立内部类的对象
in.show();
}
}

public class Demo1
{
public static void main(String[] args)
{
//new outer().new inner().show();这个是Demo1直接访问内部类方法的格式
new outer().fun();
}
}

2、静态内部类:

当内部类有静态成员的时候则该类必须为静态

  1、内部类被静态修饰符(static)所修饰后,只能访问外部类的静态成员(变量、方法)

2、外部类的静态方法要访问内部类时候,这是内部类也必须是静态的

外部类要访问静态内部类的非静态成员的格式:

 new Out.inner().shw();

外部类要访问静态内部类的静态成员的格式:

Out.inner.show();

 

下面就是一个静态类的例子

class Out
{
static int x=3;
static class inner
{
void show()
{
System.out.println(x);
}
static void show2()
{
System.out.println(x);
}

}
static void fountion()//外部类的静态方法要访问内部类时候,内部类也一定要是静态的
{
inner.show2();//外部类直接访问静态内部类
}
}

public class outdemo
{
public static void main(String[] args)
{
new Out.inner().show();//外部类访问静态内部类的非静态成员
Out.inner.show2();//外部类访问静态内部类的静态成员

}
}

3、

三、局部内部类

格式:

Class outer
{
  Void show()
  {
  Class inner
  {
  Void fun()
  {
  
  }
  }
  }
}


当内部类定义在局部的时候

1、不可以被成员修饰符所修饰(static、public、private)

2、可以直接访问外部类的成员,因为内部类持有外部类的引用

3、不可以访问他所在局部的局部变量,只能访问被fianl修饰的局部变量

class Outer
{
int x=4;
void show(final int a)//局部变量要被final所修饰
{
class iner
{
void fountion()
{
System.out.println(a);
}
}
new iner().fountion();//要先建立内部类的对象
}
}
public class Demo2
{
public static void main(String[] args)
{
Outer yy=new Outer();
yy.show(4);
yy.show(8);
}
}


四、匿名内部类(简写内部类)

1、定义匿名内部类的前提:内部类必须是继承一个类或者实现一个接口

2、匿名内部类的定义格式:

New  父类或接口名()

{

子类的内容

}

3、匿名内部类就是一个匿名子类对象

匿名内部类的定义的方法最好不要超过三个

abstract class fu
{
abstract void show();
}
class outer2
{
int x=3;
/*class Inner extends fu//不是使用匿名内部类
{
int x=2;
void show()
{
System.out.println(x);
}
}*/

void funtion()
{
//new Inner().show();
/*1.第一种匿名内部类的使用:new fu()
{

void show()

{
System.out.println(x);
}
}.show();//一个对象应用show()
*/
//第二种内部类的使用:
fu d=new fu()
{

void show()

{
System.out.println(x);
}
void show2()
{
System.out.println("x");
}
};
d.show();
//d.show()2;编译失败   父类没有show2的方法

}
}
public class NIming
{
public static void main(String[] args)
{

new outer2().funtion();
}
}


---------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ---------------------

-详细请查看:http://edu.csdn.net
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐