黑马程序员_面向对象(2) 接口&抽象类&内部类

来源:互联网 发布:刺客信条起源优化补丁 编辑:程序博客网 时间:2024/06/06 20:13
-------android培训java培训、期待与您交流! ----------

一.抽象类

特点:

1.方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰。抽象方法必须定义在抽象类中。该类必须也被abstract修饰。

2.抽象类不可以被实例化。为什么?因为调用抽象方法没有意义。

3.抽象类必须由其子类覆盖所有的抽象方法后,该子类才可以实例化。否则,这个子类还是抽象类

抽象类和一般类区别。

相同点:抽象类和一般类都是用来描述事物的,都在内部定义了成员。

不同:

1.一般类有足够的信息描述事物,抽象类描述事物的信息有可能不足。

2.一般类中不能定义抽象方法,只能定义非抽象方法。抽象类中既可以定义抽象方法也可以定义非抽象方法。

3.一般类可以被实例化,抽象类不可以被实例化。

5.抽象类一定是个父类吗?

是的。因为需要子类覆盖其方法后才可以对子类实力话


抽象类中是否有构造函数?
有,抽象类是一个父类,要给子类提供实例的初始化

abstract 关键字,和哪些关键字不能共存。
final:不行,被final修饰的类不能有子类。而被abstract修饰的类一定是一个父类。
private: 不行,抽象类中的私有的抽象方法,不被子类所知,就无法被复写。而抽象方法出现的就是需要被复写。
static:不行,如果static可以修饰抽象方法,那么连对象都省了,直接类名调用就可以了。可是抽象方法运行没意义。
 
抽象类代码eg:
// 描述员工class Employee{private String name;private String id;private double pay;Employee(String name,String id,double pay){this.name = name;this.id = id;this.pay = pay;}// 抽象方法public abstract void work();}// 描述经理class Manager extends Employee{private int bonus;Manager(String name,String id,double pay,int bonus){super(name,id,pay);this.bonus = bonus;}// 覆写public void work(){System.out.println("manager work");}}// 描述工人class Pro extends Employee{Pro(String name,String id,double pay){super(name,id,pay);}//覆写public void work(){System.out.println("pro work");}}

面试题: 抽象类与接口区别:
   声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。  
   接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口
-------------------------------------------------------------------------------------------------------------------------

二.接口

接口:是不可以创建对象的,因为有抽象方法。

需要被子类实现,子类对接口中的抽象方法全都覆盖后,子类才可以实例化。

否则子类是一个抽象类。

 

接口可以被类多实现,也是对多继承不支持的转换形式。java支持多实现,中间用逗号分割。也可以在继承一个类的同时实现多个接口。

 

接口中的常量都是静态的,可以静态调用,也可以通过接口名调用。

 

接口的特点:

1.接口是对外暴漏的规则

2.接口是程序的扩展

3.接口可以多实现

4.类与接口之间是实现关系,而且类可以继承一个类的同时实现多个接口。

5.接口与接口之间可以有继承关系。都没有方法体甚至可以多继承。

 eg: 

interface Inter{public static final int NUM = 3;public abstract void show();}interface InterA{public abstract void show();}class Demo{public void function(){}}class Test extends Demo implements Inter,InterA{public void show(){}}

接口与抽象类 共 性:都是不断抽取出来的抽象的概念

接口与抽象类区别:

区别 1:抽象类体现继承关系,一个类只能单继承,接口体现实现关系,一个类可以多实现

区别 2:抽象类是继承,是 "is a "关系,接口是实现,是 "like a"关系

区别 3:抽象类中可以定义非抽象方法,供子类直接使用,接口的方法都是抽象,接口中的成员都有固定修饰符

 

eg:
 
interface A{void methodA();}interface B //extends A{void methodB();}interface C extends B,A//接口之间可以多继承{void methodC();}class D implements C{public void methodA(){}public void methodC(){}public void methodB(){}}class InterfaceDemo {public static void main(String[] args) {Test t = new Test();System.out.println(t.NUM);//接口中的常量都是静态的,可以静态调用,也可以通过接口名调用。System.out.println(Test.NUM);System.out.println(Inter.NUM);}}

接口多态应用:
eg:
 
/*需求:数据库的操作。数据是:用户信息。1,连接数据库。JDBC  Hibernate2,操作数据库。c create r read  u update  d delete3,关闭数据库连接。*/interface UserInfoDao{public void add(User user);public void delete(User user);}class UserInfoByJDBC implements UserInofDao{public void add(User user){1,JDBC连接数据库。;2,使用sql添加语句添加数据。;3,关闭连接。}public void delete(User user){1,JDBC连接数据库。;2,使用sql添加语句删除数据。;3,关闭连接。}}class UserInfoByHibernate implements UserInfoDao{public void add(User user){1,Hibernate连接数据库。;2,使用sql添加语句添加数据。;3,关闭连接。}public void delete(User user){1,Hibernate连接数据库。;2,使用sql添加语句删除数据。;3,关闭连接。}}class  DBOperate{public static void main(String[] args) {//UserInfoByJDBC ui = new UserInfoByJDBC();//UserInfoByHibernate ui = new UserInfoByHibernate();UserInfoDao ui = new UserInfoByHibernate();ui.add(user);ui.delete(user);}}

接口应用:
/*需求:电脑运行实例,电脑运行基于主板。*/interface PCI{public void open();public void close();}class MainBoard{public void run(){System.out.println("mainboard run ");}public void usePCI(PCI p)//PCI p = new NetCard()//接口型引用指向自己的子类对象。{if(p!=null){p.open();p.close();}}}class NetCard implements PCI{public void open(){System.out.println("netcard open");}public void close(){System.out.println("netcard close");method();}}class SoundCard implements PCI{public void open(){System.out.println("SoundCard open");}public void close(){System.out.println("SoundCard close");}}class DuoTaiDemo5 {public static void main(String[] args) {MainBoard mb = new MainBoard();mb.run();mb.usePCI(null);mb.usePCI(new NetCard());mb.usePCI(new SoundCard());}}

-------------------------------------------------------------------------------------------------------------------------

三.内部类

1,内部类可以直接访问外部类中的成员,包括私有。

之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this

2,外部类要访问内部类,必须建立内部类对象

eg:

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 out = new Outer();out.method();//直接访问内部类中的成员。//Outer.Inner in = new Outer().new Inner();//in.function();}}

访问格式:
1,当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。
可以直接建立内部类对象。
格式
外部类名.内部类名  变量名 = 外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();


2,当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();
在外部其他类中,如何直接访问static内部类的静态成员呢?
uter.Inner.function();
注意:当内部类中定义了静态成员,该内部类必须是static的。
 当外部类中的静态方法访问内部类时,内部类也必须是static的。


内部类定义在局部时,
1,不可以被成员修饰符修饰
2,可以直接访问外部类中的成员,因为还持有外部类中的引用。
     但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量

eg:

class Outer{int x = 3;void method(final int a){               // 访问finall 修饰的局部变量final int y = 4;            // 不可以有成员修饰符修饰class Inner{void function(){System.out.println(y);}}   new Inner().function();}}class  InnerClassDemo3{public static void main(String[] args) {Outer out = new Outer();out.method(7);out.method(8);}}

匿名内部类:
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
     内部类必须是继承一个类或者实现接口。
3,匿名内部类的格式:  new 父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个
    eg:
abstract class AbsDemo{abstract void show();}class Outer{int x = 3;/*class Inner extends AbsDemo{int num = 90;void show(){System.out.println("show :"+num);}void abc(){System.out.println("hehe");}}*/public void function(){//AbsDemo a = new Inner();//Inner in = new Inner();//in.show();//in.abc();                 //内部类AbsDemo d = new AbsDemo(){int num = 9;void show(){System.out.println("num==="+num);}void abc(){System.out.println("haha");}};d.show();//d.abc();//编译失败;}



-------android培训java培训、期待与您交流! ----------