Java学习笔记16---抽象类与接口的浅显理解
抽象类是由abstract修饰的类,定义方式如public abstract class A{...}。
接口由interface修饰,定义方式如public interface B{...}。
抽象类与接口的具体特性见下文。
抽象类:
(1).抽象类中由abstract修饰的方法称为抽象方法,抽象方法没有具体实现,要等子类继承后再实现;声明方式如public abstract void run();。
(2).只要某类中有一个方法为抽象方法,该类就必须要定义为抽象类。
(3).抽象类不一定有抽象方法,也不一定没有非抽象方法,或者说抽象类可以没有抽象方法,也可以有非抽象方法;也就是说,一个类是不是抽象类,不是由类中是否有抽象方法决定的,而是在定义类时就确定了的,只要是由abstract修饰的类就是抽象类。对于抽象类中不含抽象方法这一点,如果不希望实例化某个类时,可以如此。
(4).非抽象的子类继承抽象类后,必须实现父类的所有抽象方法;由于子类继承了父类的所有方法,所以,如果还有未实现的抽象方法的话,该子类就应该定义为抽象类了。继承抽象类时使用关键字extends。
(5).抽象的子类继承抽象类后,可以不实现父类的抽象方法,也可以定义自己的抽象方法。
(6).抽象类有构造方法,可以有成员变量,但不能实例化;需要通过继承它的子类来间接实例化。抽象类之所以叫抽象类,正是因为它比较抽象,不能具体化成某个对象,也就是说实例化的时候根本不知道要把它实例化成一个什么东西,所以它没法实例化;比如,有一个抽象类叫“生物”,实例化的时候这个“生物”长什么样呢,大家都不知道,而当“狗”这个子类继承“生物”后,再实例化狗,就知道应该怎么实例化了,狗是一个具象的概念,大体的轮廓大家都知道,至于再具体一点,哈皮狗啊吉娃娃啊,这又属于“狗”的子类了。
接口:
(1).接口中的所有方法都是抽象方法。
(2).接口内的变量都是public static final的,而且必须是这样的,即使没有显式声明;也就是说,接口内的变量是静态的、不能修改的;定义时要赋初值,通过接口名来访问。一般不在接口中定义变量,我理解的是,接口可以由各种各样的类来实现,这些类可以是完全不相干的类,如果在接口中定义了变量的话,这些变量就是由实现接口的所有类共享的,实际上这些类不一定有这么些共同的属性存在,所以最好不在接口中定义变量,有需要就在各个类中各自定义比较好。
(3).接口要由类来实现,所有方法都要实现;类只能继承一个父类,但可以实现多个接口,接口之间用逗号分隔,如 class A implements interface1,interface2。我们可以把类想像成一块软软的面团,把接口当成各种各样的豆子,花生豆是一种接口,红豆是一种接口,绿豆也是一种接口;当类要实现接口时就把豆子嵌到面团上,面团上可以按上好多种类的豆子,也即类可以实现多个接口。
(4).接口没有构造方法,不能实例化;从这也可以理解为什么接口中的变量要是static、final的。可以把接口当成一种标准,一种固定的东西,不轻易改变,像上面的各种豆子一样,有类需要实现接口就按上一种豆子,而这些豆子不需要自己生成新的豆子,只有面团上要嵌入豆子时才拿来用,也就是说不需要生成一个接口对象,只有类需要它的时候才去实现它。
抽象类与接口都是为了继承与多态,它们都需要子类来继承才有意义,最终目的是为了多态;子类重写了父类的方法,再通过向上转型,由父类对象引用指向子类对象,达到运行时动态调用子类方法的目的。
抽象类是某一类事物的一种抽象,而接口不是类,它只定义了某些行为;如,“生物”类虽然抽象,但有“狗”类的雏形,接口中的run方法可以由狗类实现,也可以由汽车实现。
如有错误,欢迎指正。
另:如需转载,请在标题注明(转载),并在正文加上本文链接:http://www.cnblogs.com/chanchan/p/7888324.html
其他的话:
最近在不同的地方有两次都是偶然间发现有其他人奉行“拿来主义”,在其自己的平台上发表本人的学习笔记。我并没有标榜自己写得有多好或怎样,但看到这样的情况心里不免有点不舒服。毕竟这是我认认真真、辛辛苦苦一个字一个字码出来的,而且是牺牲自己的睡眠时间挤时间写出来的,因为每天要等娃睡了我才有点时间干点自己的事情。大家都不容易,还希望每个人都能尊重别人的劳动成果吧。
具体例子如下:
包animals中定义了Animal类、Mammal类、Dog类,其中Animal、Mammal都是抽象类,Mammal类继承了Animal类,Dog类继承了Mammal类;
还定义了两个接口,Interface1和Interface2,Dog类分别实现了这两个接口。
结果就不一一分析了。
附代码:
package animals;
public abstract class Animal {
public Animal() {
System.out.println("Animal constructor");
}
public abstract void eat();
public abstract void sleep();
}
package animals;
public abstract class Mammal extends Animal {
int mam = 3;
public Mammal() {
System.out.println("Mammal constructor");
}
public abstract void run(int a);
public abstract void run();
public void breathe() {
System.out.println("Mammal:breathe");
}
}
package animals;
public interface Interface1 {
int infc1 = 2;
public abstract void run();
}
package animals;
public interface Interface2 {
public abstract void swim();
}
package animals;
public class Dog extends Mammal implements Interface1,Interface2 {
public Dog() {
System.out.println("Dog constructor");
}
//animal
public void eat() {
System.out.println("eat");
}
//animal
public void sleep() {
System.out.println("sleep");
}
//mammal
public void run(int a) {
System.out.println("a=" + a);
System.out.println("run(a)");
}
//interface1
public void run() {
System.out.println("run");
}
//interface2
public void swim() {
System.out.println("swim");
}
public static void main(String[] args) {
Dog dogT = new Dog();
Mammal mal = dogT;//向上转型
Animal ani = dogT;//向上转型
Interface1 infc1 = dogT;//向上转型
Interface2 infc2 = dogT;//向上转型
System.out.println(dogT.mam);
System.out.println(dogT.infc1);
System.out.println(Dog.infc1);
System.out.println("dogT.eat():");
dogT.eat();
System.out.println("dogT.sleep():");
dogT.sleep();
System.out.println("dogT.run(8):");
dogT.run(8);
System.out.println("dogT.run():");
dogT.run();
System.out.println("dogT.swim():");
dogT.swim();
System.out.println("mal.eat():");
mal.eat();
System.out.println("mal.sleep():");
mal.sleep();
System.out.println("mal.run(9):");
mal.run(9);
System.out.println("mal.run():");
mal.run();
System.out.println("ani.eat():");
ani.eat();
System.out.println("ani.sleep():");
ani.sleep();
System.out.println("infc1.run():");
infc1.run();
System.out.println("infc2.swim():");
infc2.swim();
}
}
输出结果如下:
Animal constructor
Mammal constructor
Dog constructor
3
2
2
dogT.eat():
eat
dogT.sleep():
sleep
dogT.run(8):
a=8
run(a)
dogT.run():
run
dogT.swim():
swim
mal.eat():
eat
mal.sleep():
sleep
mal.run(9):
a=9
run(a)
mal.run():
run
ani.eat():
eat
ani.sleep():
sleep
infc1.run():
run
infc2.swim():
swim
Java学习笔记16---抽象类与接口的浅显理解的更多相关文章
- 0026 Java学习笔记-面向对象-抽象类、接口
抽象方法与抽象类 抽象方法用abstract修饰,没有方法体部分,连花括号都不能有: 抽象方法和抽象类都用abstract修饰 包含抽象方法的类一定是抽象类:但不包含抽象方法的类也可以是抽象类 不能创 ...
- Java学习笔记之抽象类与接口
抽象类(abstract) 抽象类概述:一个类被abstract修饰表示这个类是抽象类, 自己定义方法但是不实现方法,后代去实现 抽象方法: 一个方法被abstract修饰表示这个方法是抽象方法 ...
- 【Java学习笔记之二十六】深入理解Java匿名内部类
在[Java学习笔记之二十五]初步认知Java内部类中对匿名内部类做了一个简单的介绍,但是内部类还存在很多其他细节问题,所以就衍生出这篇博客.在这篇博客中你可以了解到匿名内部类的使用.匿名内部类要注意 ...
- Java学习日记-7 抽象类和接口
一.抽象类 abstract修饰:类和类中的方法 抽象方法:abstract type name(parameter-list);(abstract不能修饰static方法和构造函数) 引用:抽象类有 ...
- [core java学习笔记][第六章接口与内部类]
接口域内部类 接口 描述类具有什么功能,不给出具体实现. 内部类 用于设计协作关系的类集合 代理 实现任意接口的对象. 6.1 接口 接口声明 public interface Comparable ...
- java普通类、抽象类、接口、面向对象理解
1.面向对象编程: 面向对象编程的语言不止java一种,还有: simula 67(第一个面向对象语言,支持单继承和一定含义的多态和部分动态绑定): Smalltalk(第一个支持动态类型的语言,支持 ...
- Java基础学习笔记(三) - 抽象类和接口
一.抽象类 没有方法主体的方法称为抽象方法,包含抽象方法的类就是抽象类. Java中使用 abstract 关键字修饰方法和类,抽象方法只有一个方法名,没有方法体. public abstract c ...
- 吴裕雄--天生自然JAVA面向对象高级编程学习笔记:抽象类与接口的应用
abstract class A{ // 定义抽象类A public abstract void print() ; // 定义抽象方法print() }; class B extends A { / ...
- Java学习笔记16(面向对象九:补充内容)
总是看到四种权限,这里做一个介绍: 最大权限是public,后面依次是protected,default,private private修饰的只在本类可以使用 public是最大权限,可以跨包使用,不 ...
- Java 学习笔记(16)——Java数据库操作
数据库操作是程序设计中十分重要的一个部分,Java内置JDBC来操作数据库 JDBC使用 JDBC--Java Database connecting Java数据库连接:本质上JDBC定义了操作数据 ...
随机推荐
- Android 7.1 屏幕旋转流程分析
Android 7.1 屏幕旋转流程分析 一.概述 Android屏幕的旋转在framework主要涉及到三个类,结构如图 PhoneWindowManager:为屏幕的横竖屏转换的管理类. Wi ...
- Spark之搜狗日志查询实战
1.下载搜狗日志文件: 地址:http://www.sogou.com/labs/resource/chkreg.php 2.利用WinSCP等工具将文件上传至集群. 3.创建文件夹,存放数据: mk ...
- 使用邮件激活授权/ LightningChart license
在无网络连接的情况下,可以采用邮件的方式激活授权. 先打开License Manager,然后选 Activate/Deactivate via email, 如下图所示: 此邮件将自动发送到 lic ...
- SYSAUX表空间使用率高问题处理
SYSAUX表空间做为SYSTEM表空间的辅助表空间,主要存放EM相关的内容以及表统计信息,AWR快照,审计信息等,而假设SYSAUX表空间在默认条件下你假设不做不论什么配置,随着时间的推移.会膨胀的 ...
- 跨平台应用集成(在ASP.NET Core MVC 应用程序中集成 Microsoft Graph)
作者:陈希章 发表于 2017年6月25日 谈一谈.NET 的跨平台 终于要写到这一篇了.跨平台的支持可以说是 Office 365 平台在设计伊始就考虑的目标.我在前面的文章已经提到过了,Micro ...
- 关于signal和fork的思考
fork可以在linux中创建子进程.先看man手册里面的东西: SYNOPSIS #include <unistd.h> pid_t fork(void);DES ...
- mac brew install nginx遇到的坑
默认使用 brew install nginx 出现了一下的错误: p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: ...
- python self
Python要self的理由 Python的类的方法和普通的函数有一个很明显的区别,在类的方法必须有个额外的第一个参数(self),但在调用这个方法的时候不必为这个参数赋值(显胜于隐的引发). Pyt ...
- Intellij IDEA 4种配置热部署的方法
热部署可以使的修改代码后,无须重启服务器,就可以加载更改的代码. 第1种:修改服务器配置,使得IDEA窗口失去焦点时,更新类和资源 菜单Run -> EditConfiguration , 然后 ...
- 代码生成利器:IDEA 强大的 Live Templates(转)
代码生成利器:IDEA 强大的 Live Templates - 文章 - 伯乐在线http://blog.jobbole.com/110607/ 前言 Java 开发过程经常需要编写有固定格式的代码 ...