1.抽象方法、抽象类

1)抽象方法:

  • 由abstract修饰
  • 只有方法的定义,没有方法的具体实现(连{}都没有)

  由abstract修饰的方法为抽象方法,抽象方法只有方法的定义,没有方法体实现,用一个分号结尾。即:方法五要素中,抽象方法缺少了一个要素(方法体),也可以将抽象方法理解为不完整的方法。

2)抽象类:

  • 由abstract修饰
  • 包含抽象方法的类必须是抽象类,不包含抽象方法的类也可以声明抽象类(意义不大)
  • 抽象类不能被实例化
  • 抽象类是需要被继承的
      • 子类需要重写抽象类的所有抽象方法---常用
      • 子类也可以声明为抽象类---不常用
  • 抽象类的意义:
      • 封装子类所共有的属性和行为---代码复用
      • 为所有子类提供一种统一的类型---向上造型
      • 可以包含抽象方法,为所有子类提供了统一的入口,子类的实现不同,但入口是一致的

  由abstract修饰的类为抽象类,抽象类是不能实例化对象的,而一个类不能实例化是没有意义的,所以需要定义类来继承抽象类,它的子类必须重写所有的抽象方法,除非该类也声明为抽象类。

abstract class Foo{
private double c;
public Foo(double c){ //没什么意义,需要被子类重写
this.c = c;
}
public abstract double area(); //抽象方法,没有方法体,大括号也不存在
}
class Sub extends Foo{
public Sub(double c) { //需要重写构造方法
super(c);
}
public double area(){
return 0.0;
}
}
abstract class Sub2 extends Foo{ //抽象方法继承抽象方法
public Sub2(double c) { //需要重写构造方法,不需要重写抽象方法
super(c);
}
}

  

3)抽象类不可以被实例化

Foo f = new Foo();  //编译错误,抽象类不能被实例化

  即使一个类中没有抽象方法,也可以将其定义为抽象类,同样,该类不可以实例化。

  注意:abstract和final关键字不能同时修饰一个类,因为final使得类不可继承,而abstract修饰的类如果不可以继承将没有任何意义。

4)继承抽象类

  一个类继承抽象类后,必须实现其抽象方法,不同的子类可以有不同的实现。

abstract class Foo{
private double c;
public Foo(double c){ //没什么意义,需要被子类重写
this.c = c;
}
public abstract String sayHi();
}
class Sub extends Foo{
public Sub(double c) { //需要重写构造方法
super(c);
}
public String sayHi(){
return "Hello";
}
}

  

4)抽象类的意义

  • 为其子类提供一个公共的类型(父类引用指向子类对象,即向上造型)
  • 封装子类中的重复内容(成员变量和方法)
  • 定义有抽象方法,子类虽然有不同的实现,但该方法的定义是一致的(子类需要实现此抽象方法)

案例1:抽象类演示

public class AbstractDemo {
public static void main(String[] args){
// Shape s = new Shape(); //编译错误,抽象类不能被实例化
Shape[] shape = new Shape[4]; //创建Shape数组对象
shape[0] = new Circle(1); //向上造型
shape[1] = new Circle(2);
shape[2] = new Square(1);
shape[3] = new Square(2);
maxArea(shape); //调用求最大面积方法
} private static void maxArea(Shape[] shape) {
double max = shape[0].area();
int maxIndex = 0; //最大面积下标
for(int i=0;i<shape.length;i++){
double area = shape[i].area();
if(area>max){
max = area;
maxIndex=i;
}
}
System.out.println("最大面积为:"+max+"所在下标为:"+maxIndex);
}
}
abstract class Shape{ //抽象类---不完整的类
protected double c; //周长
public abstract double area(); //抽象方法---不完整
}
class Circle extends Shape{
public Circle(double c){
this.c = c;
}
public double area(){ //重写抽象方法---变不完整为完整
return 0.0796*c*c;
}
}
class Square extends Shape{
public Square(double c){
this.c = c;
}
public double area(){
return 0.0625*c*c;
}
}

  

2. 接口

  • 是一个标准、规范,遵循了这个标准就能干某件事
  • 是一种数据类型(引用类型)
  • 由interface定义,只能包含常量和抽象方法,方法默认由public abstract修饰
  • 接口不能被实例化
  • 接口是需要被实现的,通过implements关键字实现,实现类:必须重写接口中的所有抽象方法
  • 一个类可以实现多个接口,逗号分隔,若又继承又实现,必须先继承后实现
  • 接口可以继承一个或多个接口,逗号分隔(extends)

1)定义接口

  接口可以看成是特殊的抽象类。即:只包含抽象方法和常量的抽象类。通过interface关键字来定义接口。

interface Demo{
public static int x = 100;
public int y = 50;
double area(); //默认会加上public abstract修饰
public abstract void test();
}

  

2)实现接口

  与继承不同,一个类可以实现多个接口,实现的接口直接用逗号分隔,该类需要实现这些接口中定义的所有方法。通过implements关键字实现接口。接口可以作为一种类型声明变量,一个接口类型的变量可以引用实现了该接口的类的对象,通过该变量可以调用该接口中定义的方法(具体的实现类提供了方法的实现)。一个接口类型变量,引用了子类的对象,调用时,调用的是子类对象的具体的实现。

public class Test {
public static void main(String[] args){
Demo d = new Aoo(); //一个接口类型变量,引用了子类的对象,调用时,调用的是子类对象的具体的实现
d.test(); //This is Aoo
}
} interface Demo{
public static int x = 100;
public int y = 50;
double area(); //默认会加上public abstract修饰
public abstract void test();
}
class Aoo implements Demo{
public double area(){
return 0.0;
}
public void test(){
System.out.println("This is Aoo");
}
}

  

3)接口的继承

  接口间可以存在继承关系,一个接口可以通过extends关键字继承另外一个接口,子接口继承了父接口中定义的所有方法。

interface Foo{
public void funFoo();
}
interface Goo{
public void funGoo();
}
interface Hoo extends Foo,Goo{ //接口可以继承一个或多个接口,逗号分隔
public void funHoo();
}
interface Ioo{
void funIoo();
} class Joo implements Hoo,Ioo{ //一个类可以继承多个接口
public void funFoo(){} //重写父类的父类的抽象方法
public void funGoo(){} //重写父类的父类的抽象方法
public void funHoo(){} //重写父类的抽象方法
public void funIoo(){} //重写父类的抽象方法
}

  

4)接口和抽象类的区别

  • 一个类只能继承一个抽象类,但可以实现多个接口
  • 抽象类中可以包含抽象方法和非抽象方法,而接口中的所有方法均为抽象的
  • 子类继承抽象类必须实现抽象类中所有抽象方法,否则子类也必须是抽象类。而子类实现接口则必须实现接口中所有的抽象方法。

案例2:接口的演示

public class InterfaceDemo {
public static void main(String[] args){
// Inter6 o1= new Inter6(); //编译错误,接口不能被实例化
Inter6 o2 = new Moo(); //向上造型
Inter5 o3 = new Moo();
}
}
//演示接口语法
interface Inter1{
public static final int NUM = 5;
public abstract void show();
double PI = 3.14; //默认public static final修饰
void say(); //默认public abstract修饰
// int count; //编译错误,常量必须声明同时初始化
// void test(){} //编译错误,抽象方法没有方法体
} //演示接口实现
interface Inter2{
void show();
void say();
}
class Joo implements Inter2{
public void show(){}
public void say(){}
} //演示接口的多实现、继承
interface Inter3{
void show();
}
interface Inter4{
void say();
}
abstract class Koo{
abstract void test();
}
class Loo extends Koo implements Inter3,Inter4{
public void show(){}
public void say(){}
void test(){}
} //演示接口继承接口
interface Inter5{
void show();
}
interface Inter6 extends Inter5{
void say();
}
class Moo implements Inter6{
public void show(){}
public void say(){}
}

  

3. 多态

1)意义:

  1.1)同一类型的引用指向不同的对象时,有不同的实现:行为的多态:cut()、run()

  1.2)同一个对象被造型为不同的类型时,有不同的功能:对象的多态:水

2)向上造型:

  2.1)父类型的引用指向子类的对象

  2.2)能造型成为的类有:父类、所实现的接口

  2.3)能点出来什么,看引用的类型

3)强制类型转换,成功的条件有两种:

  3.1)引用所指向的对象,就是该子类型

  3.2)引用所指向的对象,实现了该接口

4)若不满足以上两个条件,则发生ClassCastException类型转换异常

  建议:在强转之前先通过instanceof判断引用指向的对象是否是该类型

4. 成员内部类:应用几率不大

1)类中套类,里面的成为Inner,外面的成为Outer

2)内部类通常只服务于外部类,对外不具备可见性

3)内部类对象通常是在外部类中创建的

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

   一般情况下,Inner对象会在Outer对象中创建(构造方法或其他方法),Inner对象中会有一个隐式的引用指向创建它的Outer类对象,外部类名.this.

5. 匿名内部类

1)若想创建一个类(子类)的对象,并且对象只被创建一次,此时该类不必命名,称之为匿名内部类

2)匿名内部类中访问外部的变量,该变量必须是final的

常见面试题:内部类有独立的.class吗? 答案:有

5. 面向对象三大特征

1)封装:

  1.1)类:封装的是对象的属性和行为

  1.2)方法:封装的是业务逻辑功能的实现

  1.3)访问控制修饰符:封装的是访问的权限

2)继承:

  2.1)作用:代码复用,通过extends来实现继承

  2.2)父类/基类:共有的

    子类/派生类:特有的

  3.3)单一继承、多接口实现

3)多态:

  3.1)意义:行为的多态、对象的多态 

  3.2)向上造型、强制类型转换(instanceof)

  3.3)多态的表现形式:重写、重载

设计规则:

1)将所有子类共有的属性和行为,抽象到父类中

2)所有子类行为都一样,设计为普通方法

  所有子类行为不一样,设计为抽象方法

3)将部分子类共有的行为,抽象到接口中

  符合既是也是的原则,使用接口

  接口是对继承的单根性的扩展——实现多继承

案例3:多态的演示

public class MultiTypeDemo {
public static void main(String[] args){
Aoo o1 = new Boo(); //向上造型(自动类型转换)
Boo o2 = (Boo)o1; //o1指向的对象就是Boo类型(强制类型转换)
Inter o3 = (Inter)o1; //o1指向的对象实现了Inter接口(强制类型转换)
// Coo o4 = (Coo)o1; //java.lang.ClassCastException:类型转换异常
if(o1 instanceof Coo){ //强转建议使用instanceof判断
Coo o5 = (Coo)o1;
}
}
} interface Inter{}
class Aoo{}
class Boo extends Aoo implements Inter{}
class Coo extends Aoo{}

案例4:多态的演示2

public class UnionPayTest {
public static void main(String[] args) {
ABCATM atm = new ABCATM(); //atm机对象
UnionPay card = new ABCImpl(); //银联卡
atm.insertCard(card); //插卡
atm.payTelBill(); //支付电话费
}
}
class ABCATM{ //农行ATM机类
private UnionPay card; //银联卡
public void insertCard(UnionPay card){ //插卡
this.card = card;
}
public void payTelBill(){ //支付电话费按钮
if(card instanceof ABC){ //是农行卡
ABC abcCard = (ABC)card; //强转为农行卡
abcCard.payTelBill("12345679845", 500);
}else{ //不是农行卡
System.out.println("不是农行卡,不能支付电话费");
}
}
} interface UnionPay{ //银联接口
public double getBalance(); //查询余额
public boolean drawMoney(double number); //取款
public boolean checkPwd(String input); //验证密码
}
interface ICBC extends UnionPay{ //工行接口
public void payOnline(double number); //在线支付
}
interface ABC extends UnionPay{ //农行接口
public boolean payTelBill(String phoneNum,double sum); //支付电话费
} class ICBCImpl implements ICBC{ //工行卡
public double getBalance(){return 0.0;}
public boolean drawMoney(double number){return true;}
public boolean checkPwd(String input){return true;}
public void payOnline(double number){}
}
class ABCImpl implements ABC{ //农行卡
public double getBalance(){return 0.0;}
public boolean drawMoney(double number){return true;}
public boolean checkPwd(String input){return true;}
public boolean payTelBill(String phoneNum,double sum){
System.out.println("支付电话费成功");
return true;
}
}

案例5:成员内部类的演示

public class InnerClassDemo {
public static void main(String[] args){
Outer outer = new Outer(100);
outer.printTime();
// Inner g = new Inner(); //编译错误
}
} class Outer{
private int time;
private Inner inner;
Outer(int time){
this.time = time;
inner = new Inner();
inner.timeInc();
}
public void printTime(){
System.out.println(Outer.this.time); //101
System.out.println(++time); //102
}
class Inner{
public void timeInc(){
time++;
}
}
}

  在Outer构造方法中创建的Inner对象会有一个隐式的引用指向创建它的Outer对象,调用Inner对象的timeInc方法,即会对Outer的time属性进行操作。

案例6:匿名内部类的演示

public class NstInnerClassDemo {
public static void main(String[] args){
/*
* 1)创建了Inter2的一个子类,但是没有名字
* 2)为该子类创建了一个对象,叫o1
* 3)大括号中的为子类的类体
*/
Inter2 o1 = new Inter2(){ }; /*
* 1)创建了Inter2的一个子类,但是没有名字
* 2)为该子类创建了一个对象,叫o2
* 3)大括号中的为子类的类体
*/
Inter2 o2 = new Inter2(){ }; int num = 5;
/*
* 1)创建了Inter1的一个子类,但是没有名字
* 2)为该子类创建了一个对象,叫o3
* 3)大括号中的为子类的类体
*/
Inter1 o3 = new Inter1(){
public void show(){
System.out.println("show");
System.out.println(num);
}
};
o3.show();
}
} interface Inter1{
void show();
}
interface Inter2{ }

  

Java抽象类、接口和内部类的更多相关文章

  1. Java抽象类接口、内部类题库

    一.    选择题 1. Person类和Test类的代码如下所示,则代码中的错误语句是(  C  ).(选择一项)   public class Person { public String nam ...

  2. Java核心技术--接口与内部类

    接口implement 继承接口,即履行"义务". 接口中所有的方法自动属于public,在接口声明中,不必提供关键字public 接口中决不能含有实例域,也不能在接口中实现方法 ...

  3. java 抽象类&接口

    1,抽象类中有构造函数吗? 有,用于给子类对象进行初始化.   2,抽象关键字不可以和那些关键字共存? private 不行 static 不行 final 不行   final关键字: 1,fina ...

  4. java抽象类,接口(接口定义,实现接口,instanceof运算符,对象转换)

    抽象类 在面向对象的概念中,所有的对象都是通过类来表述的,但并不是所有的类都能够完整的描绘对象,如果一个类中没有包含足够的信息来描绘一类具体的对象,这样的类就是抽象类.抽象类往往用来表征对问题领域进行 ...

  5. java 抽象类 接口 区别

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha 接口 里面 都是抽象方法. 接口里面的 字段 都是 public static fina ...

  6. 《thinking in java》 接口与内部类

    书本上的例子 改编后的. package test2; class A{ interface B{void f();} public class BImp implements B{public vo ...

  7. Java程序设计8——抽象类、接口与内部类

    1 抽象类 当编写一个类时,常常会为该类定义一些方法,这些方法用以描述该类的行为方式,那么这些方法都有具体的方法体.但在某些情况下,某个父类并不需要实现,因为它只需要当做一个模板,而具体的实现,可以由 ...

  8. Java抽象类、接口、内部类

    抽象类的概念: 1.Java中可以定义没有方法体的方法,还方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类: 2.如,shape类计算周长和面积的方法无法确定,那么就可以将这样 ...

  9. Java入门教程十(抽象类接口内部类匿名类)

    抽象类(abstract) 一个类只定义了一个为所有子类共享的一般形式,至于细节则交给每一个子类去实现,这种类没有任何具体的实例,只具有一些抽象的概念,那么这样的类称为抽象类. 在面向对象领域,抽象类 ...

  10. Java 抽象类与接口

    接口和内部类为我们提供了一种将接口与实现分离的更加结构化的方法. 抽象类与接口是 Java 语言中对抽象概念进行定义的两种机制,正是由于他们的存在才赋予 Java 强大的面向对象的能力.他们两者之间对 ...

随机推荐

  1. 计算机网络HTTP、TCP/IP包

    参考: TCP-IP数据包结构详解 HTTP报文格式详解 Http协议报文格式 HTTP请求/响应报文结构 [Java知识]GET和POST请求的区别

  2. HashMap为什么是线程不安全的

    HashMap底层是一个Entry数组,当发生hash冲突的时候,hashmap是采用链表的方式来解决的,在对应的数组位置存放链表的头结点.对链表而言,新加入的节点会从头结点加入. 我们来分析一下多线 ...

  3. 快速部署Kubernetes集群管理

    这篇文章介绍了如何快速部署一套Kubernetes集群,下面就快速开始吧! 准备工作 //关闭防火墙 systemctl stop firewalld.service systemctl disabl ...

  4. SQL Server(四)——查询练习(45道习题)转

    题目:设有一数据库,包括四个表:学生表(Student).课程表(Course).成绩表(Score)以及教师信息表(Teacher). 四个表的结构分别如表1-1的表(一)~表(四)所示,数据如表1 ...

  5. TensorFlow中设置学习率的方式

    目录 1. 指数衰减 2. 分段常数衰减 3. 自然指数衰减 4. 多项式衰减 5. 倒数衰减 6. 余弦衰减 6.1 标准余弦衰减 6.2 重启余弦衰减 6.3 线性余弦噪声 6.4 噪声余弦衰减 ...

  6. keycode和which

    firefox 中不支持keyCode ie9-- 不支持which firefox:上下左右键会触发kepress. chrome: 上下左右键不会触发kepress. oprea:上下左右键不会触 ...

  7. Unity5 AssetBundle资源管理架构设计

    http://blog.csdn.net/qq_19399235/article/details/51702964 1:Unity5 资源管理架构设计(2017.4.22版本) 2:Android 热 ...

  8. php SHA256Hex加密

    function SHA256Hex($str){ $re=hash('sha256', $str, true); return bin2hex($re); }

  9. 笔记-JavaWeb学习之旅15

    Filter:过滤器 概念:当访问服务器的资源是,过滤器可以将请求拦截下来,完成一些特殊的功能 快速入门: 步骤: 定义一个类,实现接口Filter 复写方法 配置拦截路径 package com.d ...

  10. 题解 P1004 方格取数

    传送门 动态规划Yes? 设i为路径长度,(为什么i这一维可以省掉见下)f[j][k]表示第一个点到了(j,i-j),第二个点到了(k,j-k) 则 int ji=i-j,ki=i-k; f[j][k ...