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

黑马程序员-面向对象(抽象类、接口与内部类)

2013-10-30 21:00 204 查看
----------------------
ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------

抽象类

当描述一个事物的时候,如果不能确定功能函数如何定义,那么该类就可以定义为抽象类,功能函数应该描述为抽象函数。

抽象类的格式:

Abstract class Demo{

成员属性;

非抽象方法(){};

abstract抽象方法;

}


抽象的优点

1:提高代码复用性

2:强制子类实现父类中没有实现的功能

3:提高代码的扩展性,便于后期的代码维护

抽象方法存在于抽象类和接口类,有抽象方法的不一定是抽象类,也可以是接口类。

问题:抽象类可以没有抽象方法吗?

答:抽象类也可以没有抽象方法,但是这样的抽象类无实际使用意义,除非是想要一个类不能被直接实例化,则可以定义为无抽象方法的抽象类

抽象类需要注意的地方

(1)抽象类和抽象方法必须被abstract修饰

(2)抽象类中的抽象方法必须被子类实现

(3)抽象类可以同时存在抽象方法和非抽象方法

(4)抽象类可以实现(implements)接口,抽象类可继承实体类,但前提是实体类的构造函数不能被私有化

(5)非抽象类在继承抽象类的时候,必须要把所有的抽象方法实现

(6)抽象类继承抽象类的时候,可以不用实现父类的抽象方法

(7)抽象方法不能用private关键字修饰,因为抽象方法是必须要被继承的,如果被私有修饰,那么将对子类不可见

(8)抽象方法也不能static修饰,因为用static修饰的方法可以用类名调用,但是抽象方法是没有被实现的,会出错,所以…

(9)抽象方法不能用final修饰,因为被final修饰的不能被继承,而抽象方法是必须要被继承的

(10)抽象类可以有构造方法,也可以不写构造方法,抽象类虽然不能创建对象,但构造方法是有意义的,可以为子类初始化对象,简化代码

接口:

接口的使用格式:

interface 接口名
{
属性
抽象方法
}


接口的作用(红色为主要作用)

程序的解耦

提供了标准和规范

弥补了类的单继承限制

扩展了功能

接口需要注意的地方:

(1)interface接口的成员属性全是静态常量,默认的修饰符为public Static final,如果没有写,编译的时候,编译器自动加上,一般不定义静态常量

(2)接口中的成员方法全部是抽象方法,默认修饰符为public abstract,如果没有写上,编译器自动加上

(3)接口不可以存在构造函数,不能创建对象

(4)在实现接口的时候,要把接口中的所有抽象方法覆写

(5)接口中不允许存在非抽象的方法(这和抽象类有区别),因为在编译时期,编译器会给所有的方法统一加上默认的修饰符public abstract

接口的多实现

前面说到java不支持多继承,但是接口支持多实现,这个就是对不支持多继承的一个补偿
那这个的原因是什么呢
因为继承有方法体,如果允许继承多继承,如果有继承的多个类中有同名的方法,那么可能就会产生冲突
但是接口就有一点区别,却别就是在于接口里面的方法没有方法体,即使有同名的方法,也不影响,只能在覆写的时候,由使用者自定义实现内容

内部类

内部类的使用格式
格式:
外部类名.内部类名 变量名 =外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();
例子:
class Outer
{
private int x = 3;
class Inner//定义在外部类成员位置上的内部类
{
int x = 4;
void function()
{
int x = 6;
System.out.println("innner :"+Outer.this.x);
}
}
void method()
{
Inner in = new Inner();
in.function();
}
}

class  InnerClassDemo
{
public static void main(String[] args)
{
Outer.Inner in = new Outer().new Inner();
in.function ();
}
}

内部类的访问规则:
1, 内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式:外部类名.this
2,外部类要访问内部类,必须建立内部类对象。

问题1:类能不能被私有修饰

答:是可以的,因为内部类可以被私有修饰,当内部类处于外部类的成员位置的时候,可以私有修饰
但是外部类是不允许被私有修饰的
在这要注意Static修饰,修饰了内部类之后,如果内部调用的方法没有被静态修饰的话,不能被类名直接调用
回顾了一下
static 的使用规则
(1)static修饰属性,如static int num;那么这个num就是属于全局属性,所有对象共享的,可以被直接类名调用,Person
p1 = newPerson();既可以p1.num = 10;也可以Person.num = 10;这样调用

(2)static修饰方法,
int num;
public static fun(int inf)
{
this.num = inf;
}
这样是错误的,因为static修饰的方法只能调用static修饰的属性,而num没有被static修饰
其实我这之前有一个误区,一直学到内部类才察觉到,就是以为static修饰的方法,是修饰了一整个方法体,连带方法体里面的属性也被static给修饰了,其实不完全是,static只是修饰了方法名,此时方法可以通过类名调用,我过去是在于以为方法内部的属性同样必须要经过static修饰或者已经在方法外部定义为static,这个方法才能编译成功。正确的说法,所谓调用,是外部定义的。被static修饰的方法,去使用外部的属性,这叫调用,在方法体里面定义的属性,属于局部的变量,则不属于调用,所以,不需要经过static修饰,直接可用,如果外部想用该属性,必须经过内部类的类名调用,也不能直接用,因为它不属于全局属性,属于局部变量

(3)static修饰类,其实应该也就是指内部类
基于java的面向对象思想,其实可以这样想,只要把内部类看成是一个成员方法或者成员变量即可,那么使用规则如出一辙,区分好调用了内部类中自己定义的方法和属性即可。
注意:内部类的成员变量和成员函数不能单独声明为静态,只有把内部类声明为static,这个内部类才能被静态声明的方法和属性,否则编译会报错,某些内部类不能被static修饰,下面说到

内部类定义在局部时的注意事项:

(1)内部一般只出现在外部类的成员位置上,在这个位置上,可以被static修饰,但是也有例外,就是出现在外部类的方法里面,再定义一个内部类,这个内部类就不是出现在外部类的成员位置上了,而是出现在外部类成员位置的内部位置,这是局部位置,出现在这个位置的内部类,不可以被static修饰,也即是说,只有在外部类成员位置上的内部类才能被static修饰,局部内部类不能被static修饰
(2)可以直接访问外部类中的成员,因为还持有外部类中的引用。
但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。
class Outer
{
int x = 3;
void method(final int a)
{
final int y = 4;  //内部类要访问这个变量,必须用finally修饰
class Inner   // 此时内部类定义在局部位置
{
void function()
{
System.out.println(y);
}
}
new Inner().function();
}
}


匿名内部类:

匿名内部类的格式
new 接口或者抽象类()
{
覆写抽象方法
}

示例:

class Inner extends AbsDemo
{
int num = 90;
void show();
{
System.out.println("show :"+num);
}
}
可以写成内部类形式
new AbsDemo
{
int num = 90;
void show()
{
System.out.println("show :"+num);
}
}.show();//红色部分是一个对象


1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
内部类必须继承一个类或者实现接口。
问题:那怎么知道到底是继承还是实现呢?
答:使用者自己知道
3,匿名内部类的格式: new父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个。

匿名内部类的实践
class Test
{
static Inter function()//返回值为Inter的一个方法
{
return new Inter()
{
void method();
}            //红色部分是一个Inter类型的匿名内部类
//匿名内部类的格式:  new 父类或者接口(){定义子类的内容}
}
class Demo interface Inter//此时接口是Inter,内部类名为Demo
{
void method();
}
}
public class InnerTest
{
public static void main(String args[])
{
Test.function().method();
}
}

上述代码中,Test.function().method();可以分解成三部分
Test.function():Test类中有一个静态的方法function,因为通过类名调用
.method():function这个方法运算后的结果是一个对象。
而且是一个Inter类型的对象。
因为只有是Inter类型的对象,才可以调用method方法。

问题:为什么成员内部类不能有静态属性呢

首先明确内部类有四种

(1)成员内部类

(2)局部内部类

(3)静态内部类

(4)匿名内部类

答:这里说的是成员内部类,那么就排除了处于成员位置上的静态内部类,其实说的就是内部类的方法和属性不能单独设置为静态,要设置,可以,必须把内部类变成静态内部类,一起设置

建立内部类对象时应注意:

在外部类的内部可以直接使用inner s=new inner();(因为外部类知道inner是哪个类,所以可以生成对象。)

而在外部类的外部,要生成(new)一个非静态的内部类对象,需要首先创建一个外部类对象(外部类可用),然后在生成一个内部类对象。

Outer.Inner in=new Outer.new.Inner()。

注意:生成(new)一个静态内部类不需要外部类成员:这是静态内部类和成员内部类的区别。静态内部类的对象可以直接生成:

Outer.Inner in=new Outer.Inner();//这个是静态内部类的创建方式,静态内部类必须要这样声明

而不需要通过生成外部类对象来生成。这样实际上使静态内部类成为了一个顶级类

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

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