目录
5.抽象类和接口
1.抽象类
2.接口
3.抽象类和接口的区别
4.例题
1.模拟笔记本电脑接口案例
2.会员卡打折案例
3.不同几何体面积案例
4.写作文案例
6.内部类及OOP实战
1.成员内部类、局部内部类
2.匿名内部类
关键字:abstract
1.不能new这·个抽象类,只能靠子类去实现它(这就是一个约束条件)得到了抽象方法,失去了创建对象的能力,调用需要使用多态,实例化子类,来引用父类的东西
2.抽象类中可以写普通的方法
3.抽象类可以不定义抽象方法,但是有抽象方法的一定是抽象类(抽象方法必须在抽象类中)
4.抽象类存在构造器5.抽象类可以封装
6.抽象类中可以实现也可以派生,但是不能实现自己的抽象方法,可以实现父类的抽象方法
7.子类必须重写父类的所有抽象方法,除非这个类也是抽象类,那就一直继承到可以实现的类
8.抽象类默认有无参构造
9.不能用abstract修饰变量、代码块、构造器。
10.abstract定义的抽象类作为模板让子类继承,final定义的类不能被继承,更不能被重写(互斥关系)
抽象类存在的意义:
1.抽象类的核心意义就是为了被子类继承(就是为了派生子类),否则抽象类毫无意义!(就是让子类必须实现父类的抽象方法)
2.抽象类体现的是模板思想,部分实现,部分抽象,可以设计模板设计模式非法修饰符:
abstract和private就是非法组合,抽象方法要重写,private不能继承
abstract和final就是非法组合,抽象方法要重写,final修饰不能重写
abstract和static就是非法组合,静态方法类名直接调用
例:
package java_jichu.mianxiangduixiang.demo10;
//abstract 抽象类
public abstract class Action {
//约束 有人帮我们实现
//abstract 抽象方法,只有方法名字,没有方法实现
public abstract void doSomething();
}
/*
package java_jichu.mianxiangduixiang.demo10;
//抽象类的所有方法,继承了他的子类,都必须实现它的方法,除非子类也是抽象的,就需要他的子子类实现
public class A extends Action{
@Override
public void doSomething() {
}
}
*/
关键字:implements
◆普通类:只有具体实现
◆抽象类:具体实现和规范(抽象方法)都有!
◆接口:只有规范!自己无法写方法~
◆接口就是规范(约束)只能让子类实现
◆OO的精髓,是对对象的抽象,最能体现这一点的就是接口。作用:
1.约束
2.定义一些方法,让不同的人实现 就比如让十个员工去做一个接口10 -> 1
3.public abstract 接口的默认方法 void(基本数据类型) xxx();抽象方法名(设置一个形参,实现类需要实例化赋值)
4.public static final 默认常量 int A;或者int A=9
5.接口不能被实例化,因为接口中没有构造方法(不能new),调用需要子类多态父类去调用父类成员变量
6.implements可以实现多个 接口,一个类可以实现多个接口,接口和接口之间是继承关系,支持多继承或继承多个接口,多个接口的规范不能冲突,多个接口中有同样的静态方法不冲突
7.一个类继承了父类,同时又实现了接口,父类中和接口中有同名方法,默认用父类的。8.接口中只能是抽象方法和常量
9.接口中的成员都是public修饰的,写不写都是,因为规范的目的是为了公开化
10.接口没有构造器
11.一个类实现接口,必须重写完全部接口的全部抽象方法,否则这个类需要定义成抽象类然后将剩余的实现给子类的实现类去实现。
12.实现类必须要重写接口中的抽象方法。
例:
package java_jichu.mianxiangduixiang.demo11;
//抽象类 extends单继承
//类 可以实现接口 implements 接口
//实现了接口的类,就需要重写接口中的方法
public class UserServiceImpl implements UserService,TimeService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
/*
package java_jichu.mianxiangduixiang.demo11;
//interface 定义的关键字,接口都需要有实现类
public interface UserService {
//常量~ (默认有)public static final 一般不会去定义常量,接口主要是去实现里面的方法
int AGE=99;
//接口中的所有定义的方法其实都是抽象的public abstract(默认有)
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
package java_se.java_jichu.mianxiangduixiang.demo11;
public interface TimeService {
void timer();
}
*/
相同点
不同点
参数 | 抽象类 | 接口 |
---|---|---|
声 明 | 抽象类使用abstract关键字声明 | 接口使用interface关键字声明 |
实 现 | 子类使用extends关键字来继承抽象类。如果子类 不是抽象类的话,它需要提供抽象类中所有声明 的方法的实现 | 子类使用implements关键字来实现 接口。它需要提供接口中所有声明的 方法的实现 |
构 造 器 | 抽象类可以有构造器 | 接口不能有构造器 |
访 问 修 饰 符 | 抽象类中的方法可以是任意访问修饰符 | 接口方法默认修饰符是public。并且 不允许定义为 private 或者 protected |
多 继 承 | 一个类最多只能继承一个抽象类 | 一个类可以实现多个接口 |
字 段 声 明 | 抽象类的字段声明可以是任意的 | 接口的字段默认都是 static 和 final 的 |
package java_se.java_jichu.zuoye_8_9.demo01;
public class TestComputer {
public static void main(String[] args) {
/*模拟笔记本电脑接口案例
模拟笔记本电脑的功能接口
*/
Computer c1 = new Computer();
//开启电脑
c1.powerOn();
//多态 方法编译看左边,运行看右边 成员变量编译看左边,运行也看左边
USB usb1 = new USBImpl1();
//电脑里面的方法赋值为鼠标
c1.useDevice(usb1);//判断比较值
USBImpl2 usb2 = new USBImpl2();
c1.useDevice(usb2);
c1.powerOff();
}
}
/*
接口
package java_se.java_jichu.zuoye_8_9.demo01;
public interface USB {
//接入
void a1();
//拔出
void a2();
}
鼠标package java_se.java_jichu.zuoye_8_9.demo01;
import java_se.java_jichu.zuoye8_5.Rectangle;
//鼠标
public class USBImpl1 implements USB{
@Override
public void a1() {
System.out.println("接入鼠标");
}
@Override
public void a2() {
System.out.println("拔出鼠标") ;
}
public String click(){
System.out.println("点击鼠标");
return "点击鼠标";
}
}
键盘
package java_se.java_jichu.zuoye_8_9.demo01;
//键盘
public class USBImpl2 implements USB{
@Override
public void a1() {
System.out.println("接入键盘");
}
@Override
public void a2() {
System.out.println("拔出键盘");
}
public String rap(){
System.out.println("敲击键盘");
return "敲击键盘";
}
}
电脑
package java_se.java_jichu.zuoye_8_9.demo01;
public class Computer {
public void powerOn(){
System.out.println("笔记本电脑开机");
}
public void powerOff(){
System.out.println("笔记本电脑关机");
}
public void useDevice(USB usb){
usb.a1();
if (usb instanceof USBImpl1){//如果有父子关系则调用里面的方法
((USBImpl1)usb).click();//父类调用子类独有的方法需要降级调用
}
if (usb instanceof USBImpl2){
((USBImpl2)usb).rap();
}
usb.a2();
}
}
*/
package java_se.java_jichu.zuoye_8_9.demo02;
public class TextYinHang {
public static void main(String[] args) {
/*会员卡打折案例
某加油站推出了2种支付卡,一种是预存10000的金卡,后续加油享受8折优惠,另一种是预存5000的银卡 ,后续加油享受8.5折优惠。
请分别实现2种卡片进入收银系统后的逻辑,卡片需要包含主人名称,余额,支付功能。
*/
//调用jin类
Jin jin = new Jin();
//给从父类获取的封装值赋值
jin.setMoney(10000);
jin.setName("金卡王");
//给pay形参给赋一个实参
jin.pay(300);
//用完方法后剩余的金额
System.out.println("剩余: " + jin.getMoney());
System.out.println("--------------------------");
Yin yin = new Yin();
yin.setMoney(5000);
yin.setName("银卡王");
yin.pay(500);
System.out.println("剩余: " + yin.getMoney());
}
}
/*
抽象类
package java_se.java_jichu.zuoye_8_9.demo02;
public abstract class Shape {
// 两个封装属性
//客户姓名
private String name;
//客户卡内的钱
private double money;
//客户每次消费原价多少钱
abstract void pay(double money2);
//获取封装的成员变量
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
金卡
package java_se.java_jichu.zuoye_8_9.demo02;
public class Jin extends Shape{
@Override
void pay(double money2) {
System.out.println("您当前消费: " + money2);
System.out.println("您的金卡当前余额是: " + getMoney());
//优惠价:
double rs = money2 * 0.8;
System.out.println(getName() + "您实际支付:" + rs);
//更新账户余额 账户余额减消费金额*x折
setMoney(getMoney() - rs);
}
}
银卡
package java_se.java_jichu.zuoye_8_9.demo02;
public class Yin extends Shape{
@Override
void pay(double money2) {
System.out.println("您当前消费: " + money2);
System.out.println("您的银卡当前余额是: " + getMoney());
//优惠价:
double rs = money2 * 0.85;
System.out.println(getName() + "您实际支付:" + rs);
//更新账户余额
setMoney(getMoney() - rs);
}
}
*/
package java_se.java_jichu.zuoye_8_9.demo3;
public class TestMianJi {
public static void main(String[] args) {
/*不同几何体面积案例
不同几何图形的面积计算公式是不同的,但是它们具有的特性是相同的,都具有长和宽这两个属性,也都具有面积计算的方法。那么可以定义一个抽象类,
在该抽象类中含有两个属性(width 和 height)和一个抽象方法area( )。
*/
San san = new San();
san.setHeight(3);
san.setWinth(5);
san.setName("三角形");
san.area();
System.out.println("--------------");
Ju ju = new Ju("矩形",1,2);
ju.area();
}
}
/*抽象类
package java_se.java_jichu.zuoye_8_9.demo3;
public abstract class Shape {
//三个封装待设值得属性
private String name;
private double winth;
private double height;
//一个抽象方法让子类实现
abstract void area( );
//让外部可以获取和赋值封装属性
public double getWinth() {
return winth;
}
public void setWinth(double winth) {
this.winth = winth;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Shape() {
}
//子类不能继承使用父类的有参构造
public Shape(String name, double winth, double height) {
this.name = name;
this.winth = winth;
this.height = height;
}
}
三角形
package java_se.java_jichu.zuoye_8_9.demo3;
public class San extends Shape{
//子类实例化默认调用父类的无参构造
@Override
void area() {
double mj = (getWinth()*getHeight())/2;
System.out.println(getName()+"的面积为:"+mj);
}
}
矩形
package java_se.java_jichu.zuoye_8_9.demo3;
public class Ju extends Shape{
//调用父类的有参构造
public Ju(String name, double winth, double height) {
super(name, winth, height);
}
@Override
void area() {
double mj = getWinth()*getHeight();
System.out.println(getName()+"的面积为:"+mj);
}
}
*/
package java_se.java_jichu.zuoye_8_9.demo4;
import java_se.java_jichu.zuoye_8_9.demo3.San;
public class TestZW {
public static void main(String[] args) {
/*写作文案例
现在有两类学生,一类是中学生,一类是小学生,他们都要写《我的爸爸》这篇作文。
要求每种类型的学生,标题第一段和最后一段,内容必须一样。正文部分自己发挥。
请选择最优的面向对象方案进行设计。
*/
//调用作文的方法
ZuoWen zuoWen = new ZuoWen();
//调用中学生的方法
ZStudent zStudent = new ZStudent();
//给中学生的父类的属性赋值
zStudent.setName("中学生");
//输出作文的Xie方法实参值为zStudent(被调用的中学生类)
zuoWen.Xie(zStudent);
System.out.println("===============");
//调用小学生的方法
XStudent xStudent = new XStudent();
//给中学生的父类的属性赋值
xStudent.setName("小学生");
//输出作文的Xie方法实参值为xStudent(被调用的小学生类)
zuoWen.Xie(xStudent);
}
}
/*接口
package java_se.java_jichu.zuoye_8_9.demo4;
public interface XZ {
//用来限制头部和尾部内容
void first();
void lase();
}
抽象类
package java_se.java_jichu.zuoye_8_9.demo4;
public abstract class QuanBu implements XZ{
//用来后续输入是谁写的作文,如(可能出现小张的作业没有写名字,然后小王直接把小张作业写上自己名字)
//也可以不设置这个值,(如作文本上都写上了名字直接输出名字)
private String name;
//用来实现头部和尾部内容
@Override
public void first() {
System.out.println("这是头部");
}
//用来限制子类中间内容
abstract void zj();
@Override
public void lase() {
System.out.println("这是尾部");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
小学生
package java_se.java_jichu.zuoye_8_9.demo4;
public class XStudent extends QuanBu{
//小学生作文中间的实现内容
@Override
void zj() {
System.out.println("这是"+getName()+"的中部");//get调用的是在测试类给抽象类QuanBu赋值的name
}
}
中学生
package java_se.java_jichu.zuoye_8_9.demo4;
public class ZStudent extends QuanBu{
//中学生的作文中间实现内容
@Override//重写
void zj() {
System.out.println("这是"+getName()+"的中部");//get调用的是在测试类给抽象类QuanBu赋值的name
}
}
作文实现
package java_se.java_jichu.zuoye_8_9.demo4;
public class ZStudent extends QuanBu{
//中学生的作文中间实现内容
@Override//重写
void zj() {
System.out.println("这是"+getName()+"的中部");//get调用的是在测试类给抽象类QuanBu赋值的name
}
}
*/
内部类的定义
内部类就是在一个类的内部在定义一个类,内部类本身就是类的一个属性,与其他属性定义方式一致。
比如,A类中定义一个B类,那么B类相对A类来说就称为内部类,而A类相对B类来说就是外部类了。
内部类的分类
package java_jichu.mianxiangduixiang.demo12;
public class Outer {
// 一
// private int id=10;
// public void out(){
// System.out.println("这是外部类的方法");
// }
// (1)
// public class Inner{
// public void in(){
// System.out.println("这是内部类的方法");
// }
// (2)
// //获得外部类的私有属性
// public void getID(){
// System.out.println(id);
// }
// }
// 三
//局部内部类
public void method(){
class Inner{
public void in(){
}
}
}
}
//二
//一个java类中可以有多个class类,但只能有一个public class
//class A{
// public static void main(String[] args) {
//
// }
//}
/*
public static void main(String[] args) {
//new new一个外部类
Outer outer = new Outer();
//通过外部类来实现内部类
Outer.Inner inner = outer.new Inner();//成员内部类
// inner.in(); //这是内部类的方法
// inner.getID(); //10
}
*/
package java_jichu.mianxiangduixiang.demo12;
public class Test {
public static void main(String[] args) {
//没有名字初始化类,不用实例保存到变量中
new Apple().eat();
new UserService(){//UserService userService new UserService() 必须要重写里面的方法
@Override
public void hello() {
}
};
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
interface UserService{
void hello();
}