Java面向对象(三) 【面向对象深入:抽象类,接口,内部类等】
面向对象(Object Oriented)
1、抽象类
抽象就是将拥有共同方法和属性的对象提取出来。提取后,重新设计一个更加通用、更加大众化的类,就叫抽象类。
1)abstract 关键字修饰类、方法,即抽象类和抽象方法。
2)抽象类可以有具体的方法,或者全部都是具体方法,但一个类中只要有一个抽象方法,那么这个类就是抽象类,并且必须用 abstract 修饰类。
3)抽象类只能用来被继承,则子类必须实现抽象类中的全部抽象方法,否则子类也将是抽象类。抽象类也可主动继承实体类。
4)抽象类不能实例化,即不能用 new 生成实例,所以只能作为父类使用。
5)可以声明一个抽象类型的变量并指向具体子类的对象。
6)抽象类可以实现接口中的方法。
7)抽象类中可以不定义抽象方法,这样做仅仅是不让该类建立对象。
//抽象类Animal
abstract class Animal {
abstract public void shout(); //抽象方法
}
class Cat extends Animal {
//子类必须实现父类的抽象方法,否则编译错误
public void shout() {
System.out.println("喵喵喵!");
}
// 定义自己的特有方法
public void CatchMouse(){
System.out.println("抓老鼠ing....");
}
}
//测试抽象类
public class AbstractTest {
public static void main(String[] args) {
Animal animal = new Cat();// 这样new也是可以的
Cat cat = new Cat();
cat.shout();
cat.seeDoor();
}
}
AbstractTest Code
1)抽象类不能被实例化,非抽象类可以实例化。疑问解答:
1、抽象类中一定有抽象的方法?
答:不对的。抽象类中可以有抽象方法,也可以没有抽象方法。
2、有抽象方法的类,一定是抽象类?
答:对的。如果一个类中包含了至少一个抽象方法,那么该类必须是抽象类。
3、抽象类是否可以用final 修饰?
答:不可以,final 的类不能当父类,abstract的类只能当父类。互斥的。不能同时使用。
4、静态方法是否可以声明成抽象方法?
答:不可以,static 和 abstract 也是互斥的。
5、抽象方法是否可以使用 private 修饰?
答:不可以。私有的方法不能子类继承,不能继承就不能重写。 抽象方法就是为了让子类实现重写的。互斥的。
6、抽象类中定义的抽象方法,每一个抽象的方法都是定义了一个规则!!
答:每一个抽象方法,都是父类给实现的子类定义的一个规则:子类在实现父类抽象方法的时候,不管子类实现的细节如何,但是对实现的功能是有要求的。
7、抽象关键字不可以和那些关键字共存?
private => 非法的修饰符组合: abstract和private(抽象需要被覆盖)
static => 非法的修饰符组合: abstract和static
final => 非法的修饰符组合: abstract和final
8、抽象类和非抽象类的区别?
2)抽象类必须是有子类的,不然没有定义该类的意义。非抽象类不一定了。如果final 修饰就一定没有子类。
3)定义的方式不同。abstract 修饰抽象类。非抽象类不需要。
4)抽象类中可以有抽象方法。非抽象类不可以有抽象方法的。
2、接口(接口就是规范,定义的是一组规则。接口的出现将“多继承”通过另一种形式体现出来,即“多实现”)
接口相关规则:
• 接口中所有方法都是抽象的。
• 即使没有显式的将接口中的成员用public标示,也是public访问类型的
• 接口中变量默认用 public static final标示,所以接口中定义的变量就是全局静态常量。
• 可以定义一个新接口,用extends去继承一个已有的接口
• 可以定义一个类,用implements去实现一个接口中所有方法。
• 可以定义一个抽象类,用implements去实现一个接口中部分方法。
如何定义接口?
如何实现接口?
• 子类通过implements来实现接口中的规范
• 接口不能创建实例,但是可用于声明引用变量类型。
• 一个类实现了接口,必须实现接口中所有的方法,并且这些方法只能是public的。
• Java的类只支持单继承,接口支持多继承
接口的多继承:接口完全支持多继承。和类的继承类似,子接口扩展某个父接口,将会获得父接口中所定义的一切。
example
package com.boom0831;
/**
* 测试接口和实现类
* @author Administrator
*
*/
public class InterfaceTest { public static void main(String[] args) {
Volant v = new Angel();
v.fly(); Honest h = new GoodMan();
h.helpOther();
} }
/**
* 飞行的接口
* @author Administrator
*
*/
interface Volant{
int FLY_HEIGHT = 10000;
void fly();
}
// 善良的接口,天使接口
interface Honest{
void helpOther();
} // 天使实现了飞行和善良的接口
class Angel implements Volant,Honest{ // 实现类可以实现多个父接口
// 实现飞行的接口
@Override
public void fly() {
System.out.println("Angel.fly");
}
// 实现天使接口
@Override
public void helpOther() {
System.out.println("Angel.helpOther");
}
} /**
* 好人和坏人分别实现不同的接口
* @author Administrator
*
*/
class GoodMan implements Honest{
@Override
public void helpOther() {
System.out.println("GoodMan.Honest");
}
} class Birdman implements Volant{
@Override
public void fly() {
System.out.println("Birdman.Volant");
}
}
InterfaceTest Code
example
package com.boom0831; public class UsbInterface { public static void main(String[] args) {
Usb u1 = new Fan();
u1.run();
Usb u2 = new Keyboard();
u2.run();
Usb u3 = new Mouse();
u3.run();
} }
interface Usb{
void run();
} class Fan implements Usb{
@Override
public void run() {
System.out.println("小风扇实现了USB接口。吹啊吹啊 我的骄傲放纵!");
}
} class Keyboard implements Usb{
@Override
public void run() {
System.out.println("键盘实现了USB接口。开始疯狂的敲代码!funk!");
}
} class Mouse implements Usb{
@Override
public void run() {
System.out.println("鼠标实现了USB接口。开始了蛇皮风骚走位!");
}
}
UsbInterface Code
example 升级版
package com.boom0831;
/**
* UsbPlug多实现
* @author Administrator
*
*/
public class ImplementTest { public static void main(String[] args) {
Computer computer = new Computer(); Mouse mouse = new Mouse();
Keyboard keyboard = new Keyboard();
computer.load(mouse);
computer.load(keyboard); System.out.println("------ 扩展设备:小风扇 、 小台灯 ------");
computer.load(new Fun());
computer.load(new Light()); } } //通过usb 接口 给 设备供电的规则
interface UsbPlug{
/**
* 如何通过usb接口让设备运转起来的规则
*/
void run();
} //功能描述的是 插槽如何和usb连接 通电
interface UsbSocket{
/**
* 插槽如何 连接 usb 插头,给插头通电
* @param plug 被装备的 usb 插头
*/
void load(UsbPlug plug);
} //具有usb 功能的鼠标
class Mouse implements UsbPlug{
@Override
public void run() {
System.out.println("鼠标通过UsbPlug接口,鼠标通电成功,蛇皮走位操控电脑!");
}
} class Keyboard implements UsbPlug{
@Override
public void run() {
System.out.println("键盘通过UsbPlug接口,键盘通电成功,疯狂敲代码到崩溃!"); }
} class Fun implements UsbPlug{
@Override
public void run() {
System.out.println("小风扇通过UsbPlug接口,小风扇通电成功,吹啊吹啊 我的骄傲放纵!");
}
} class Light implements UsbPlug{
@Override
public void run() {
System.out.println("小台灯通过UsbPlug接口,小台灯通电成功,发出奥特之光!");
}
} class Computer implements UsbSocket{
// 电脑具有装载UsbPlug接口的功能
public void load(UsbPlug plug){
plug.run();
}
}
Implement Code
3、内部类
在类内部定义的类为成员内部类,在方法里定义的类为局部内部类,被 static 修饰的为静态内部类。一个类中可有多个内部类。
内部类的作用:
1. 由于内部类提供了更好的封装特性,并且可以很方便的访问外部类的属性。所以,在只为外部类提供服务的情况下可以优先考虑使用内部类。
2. 使用内部类间接实现多继承:每个内部类都能独立地继承一个类或者实现某些接口,所以无论外部类是否已经继承了某个类或者实现了某些接口,对于内部类没有任何影响。
.成员内部类(可以使用private、default、protected、public任意进行修饰。 类文件:外部类$内部类.class)
a) 非静态内部类(外部类里使用非静态内部类和平时使用其他类没什么不同)
i. 非静态内部类必须寄存在一个外部类对象里。如果有一个非静态内部类对象那么一定存在对应的外部类对象。非静态内部类对象单独属于外部类的某个对象。
ii. 非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员。
iii. 非静态内部类不能有静态方法、静态属性和静态初始化块。
iv. 外部类的静态方法、静态代码块不能访问非静态内部类,包括不能使用非静态内部类定义变量、创建实例。
v. 成员变量访问要点:
1. 内部类里方法的局部变量:变量名。
2. 内部类属性:this.变量名。
3. 外部类属性:外部类名.this.变量名。
4.创建内部类格式:外部类.内部类 变量名 = new 外部类().new 内部类();
package com.boom.innerclass; /**
* 测试非静态内部类
*
* @author Administrator
*
*/
public class InnerClass { public static void main(String[] args) {
// 创建内部类对象
Outer.Inner inner = new Outer().new Inner();
inner.show();
} } class Outer {
private int age = 10; public void testOuter() { } // 非静态内部类Inner
class Inner {
int age = 30; public void show() {
int age = 40;
System.out.println("访问外部内成员变量age:" + Outer.this.age);//
System.out.println("内部类内成员变量age:" + this.age); //
System.out.println("局部变量age:" + age);//
}
}
}
b) 静态内部类 内部类前面被static关键字所修饰
1. 当一个静态内部类对象存在,并不一定存在对应的外部类对象。 静态内部类的实例方法不能直接访问外部类的实例方法。
2. 静态内部类看做外部类的一个静态成员。 外部类的方法中可以通过:“静态内部类.名字”的方式访问静态内部类的静态成员,通过 new 静态内部类()访问静态内部类的实例。
c) 匿名内部类 适合那种只需要使用一次的类,一般Android使用的较多。
1. 匿名内部类没有访问修饰符。
2. 匿名内部类没有构造方法。因为它连名字都没有那又何来构造方法.
• 只能实现一个接口,或者继承一个父类
• 适合创建那种只需要一次使用的类,不能重复使用。比较常见的是在图形界面编程GUI里用得到。
• 匿名内部类要使用外部类的局部变量,必须使用final修饰该局部变量
d) 局部内部类:定义在方法内部的,作用域只限于本方法,称为局部内部类。
局部内部类的的使用主要是用来解决比较复杂的问题,想创建一个类来辅助我们的解决方案,到那时又不希望这个类是公共可用的,所以就产生了局部内部类。局部内部类和成员内部类一样被编译,只是它的作用域发生了改变,它只能在该方法中被使用,出了该方法就会失效。局部内部类在实际开发中应用很少。
Java面向对象(三) 【面向对象深入:抽象类,接口,内部类等】的更多相关文章
- Java入门教程十(抽象类接口内部类匿名类)
抽象类(abstract) 一个类只定义了一个为所有子类共享的一般形式,至于细节则交给每一个子类去实现,这种类没有任何具体的实例,只具有一些抽象的概念,那么这样的类称为抽象类. 在面向对象领域,抽象类 ...
- Effective Java 第三版——38. 使用接口模拟可扩展的枚举
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 【Java】对象、类(抽象类与内部类)、接口
博文内容概况 对象和类 抽象类 接口 内部类 对象和类 对象是对客观事物的抽象,类是对对象的抽象.类是一种数据类型,其外观和行为由用户定义.类中可以设置两种类型的元素:字段(有时被称为数据成员)和方法 ...
- java面向对象(三)之抽象类,接口,向上转型
java类 java类分为普通类和抽象类,接口,上一节我大概讲了java类的一般格式,今天将抽象类和接口.同时讲一下它们是怎样存储的. 最重要的是理解为什么要有抽象和接口,这样学下来你猜不会迷茫,才能 ...
- 【Java基础】【09面向对象_多态&抽象类&接口】
09.01_面向对象(多态的概述及其代码体现) A:多态(polymorphic)概述 事物存在的多种形态 B:多态前提 a:要有继承关系. b:要有方法重写. c:要有父类引用指向子类对象. C:案 ...
- Java千百问_05面向对象(005)_接口和抽象类有什么差别
点击进入_很多其它_Java千百问 1.接口和抽象类有什么差别 在Java语言中.抽象类abstract class和接口interface是抽象定义的两种机制. 正是因为这两种机制的存在,才赋予了J ...
- Java学习笔记10(面向对象三:接口)
接口: 暂时可以理解为是一种特殊的抽象类 接口是功能的集合,可以看作是一种数据类型,是比抽象类更抽象的"类" 接口只描述所应该具备的方法,并没有具体实现,具体实现由接口的实现类(相 ...
- Java语言简介、基础组成、封装、继承、多态、抽象类、内部类、接口
目录 Java简介 Java语言基础组成 面向对象 对象 封装 构造函数 this关键字 static(静态关键字) 主函数 静态什么时候用呢? 面向对象(数组工具对象建立) 设计模式 继承 成员变量 ...
- Java进阶(三十六)深入理解Java的接口和抽象类
Java进阶(三十六)深入理解Java的接口和抽象类 前言 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太 ...
- python面向对象 : 抽象类(接口类),多态,封装(私有制封装)
一. 抽象类(接口类) 与java一样, python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类, 它的特殊之处在于只能被继承, 不能被实例化. 从设计角度去看, 如果类是从现实对 ...
随机推荐
- vue3.x版本安装vue-cli建项目
vue-cli版本在3以上 全局安装vue-cli npm install -g @vue/cli 建立项目工程,假设项目建在e:\vueProject\vue-cli3.0+目录下: 先进入此目录: ...
- Visual Studio工具
下载地址: https://code.visualstudio.com 插件安装: http://blog.csdn.net/u011127019/article/details/53158660 下 ...
- 【HANA系列】SAP HANA SQL IFNULL和NULLIF用法与区别
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA SQL IFN ...
- CenterNet算法笔记(目标检测论文)
论文名称:CenterNet: Keypoint Triplets for Object Detectiontection 论文链接:https://arxiv.org/abs/1904.08189 ...
- Vue对象提供的属性功能
一. 过滤器 过滤器,就是vue允许开发者自定义的文本格式化函数,可以使用在两个地方:输出内容和操作数据中. 定义过滤器的方式有两种: 1. 使用Vue.filter()进行全局定义 示例: < ...
- python下对目录&文件的操作
Windows桌面上: 总文件夹 子文件夹01 文档01.txt-------------------------------------------------------------------- ...
- MySQL中的聚集索引和辅助索引
MySQL中的聚集索引和辅助索引 当你定义一个主键时,innodb存储引擎就把他当做聚集索引 如果你没有定义一个主键,则innodb定位到第一个唯一索引,且改索引的所有列值均为非空,就将其当做聚集索引 ...
- java 重写的 几大注意点
Single Dispatch class Parent { void print(String a) { log.info("Parent - String"); } void ...
- 菜鸟系列k8s——快速部署k8s集群
快速部署k8s集群 1. 安装Rancher Rancher是业界唯一完全开源的企业级容器管理平台,为企业用户提供在生产环境中落地使用容器所需的一切功能与组件. Rancher2.0基于Kuberne ...
- 学习笔记:CentOS 7学习之十一:文件的重定向
1.文件描述符定义 文件描述符:是内核为了高效管理已被而打开的文件所创建的缩影,用于指向被打开的文件,所有执行I/O操作的系统调用都通过文件描述符:文件描述符是一个简单的非负整数,用于标明每一个被进程 ...