一、抽象方法
概念:只有方法的声名 没有方法的实现即方法体 用abstract关键字修饰
2语法:
访问修饰符 abstract 返回类型 方法的名称(参数列表);
例子: public abstract void showInfo();
3.作用: 简化方法的编写 不用编写方法体
一般用于父类,子类继承时直接重写方法
4.注意点:抽象方法必须在抽象类中
二、抽象类
1.概念: 抽象类也是一个普通类 使用abstract关键字修饰
2.语法:
访问修饰符 abstract class 类名 {}
例子:public abstract class Student{}
3.成员:
A.成员变量
B.构造方法
C.方法: 成员方法 抽象方法
4.抽象类与抽象方法关系:
抽象方法必须在抽象类 但是抽象类可以没有抽象方法
5.注意点:
A.抽象类是不能实例化对象
用向上转型来new一个引用父类类型的对象
B.抽象类的构造方法一般用给子类进行调用
C.子类必须实现抽象类中所有的抽象方法 除非子类也是抽象类
三、接口
1.概念 提供一些规范和约束 规范:就是定义了一些抽象方法
2. 使用关键字:interface
3. 定义的语法:
访问修饰符 interface 接口名称{}
例子:public interface inner{}
注意点:
A.将类的关键字换成interface B.接口编译之后也是字节码文件
4.成员:
变量:接口的变量都是静态的常量 默认都使用 public static final来进行修饰
构造方法:没有构造方法
方法: 在jdk1.8之后 有抽象方法(方法默认都会加上 public abstract)可以有默认方法(default关键字来进行修饰方法)私有的方法(private) 以及静态方法(static)
5.注意点
A.接口不能实例化对象
B.接口中的实现类必须实现接口中所有的抽象方法
C.接口可以有多个实现类
6.接口的实现类:
概念:实现接口的普通的java类
关键字: implements
分类:单实现 多实现
7.单实现:
概念:实现类实现一个接口
语法: 访问修饰符 class 类名 implements 接口名 {}
例子:public class Impl implements inner{}
原则:实现接口中所有的抽象方法
8.多实现:
概念:实现类实现多个接口 解决java单继承的问题
语法:访问修饰符 class 类名 implements 接口1,接口2 {}
例子:public class Impl implements inner,Inner{}
原则:实现接口中所有的抽象方法
注意点:一个实现类接多个接口 不同接口里有相同名的抽象方法 实现类只需要实现一个抽象类方法 因为接口的抽象方法没有方法体 需要实现类(子类)来重写
案例:
package com.qf.demo06;
public interface Pager {
String getPager();
}
package com.qf.demo06;
public class A3Pager implements Pager {
@Override
public String getPager() {
return "A3纸张";
}
}
package com.qf.demo06;
public class A4Pager implements Pager {
@Override
public String getPager() {
return "A4纸张";
}
}
package com.qf.demo06;
public interface Link {
String getLink();
}
package com.qf.demo06;
public class BlackLink implements Link{
@Override
public String getLink() {
return "黑色墨盒";
}
}
package com.qf.demo06;
public class ColorLink implements Link {
@Override
public String getLink() {
return "彩色墨盒";
}
}
package com.qf.demo06;
public class Printer {
private Pager pager;
private Link link;
public void setPager(Pager pager) {
this.pager = pager;
}
public void setLink(Link link) {
this.link = link;
}
public void print(){
System.out.println(pager.getPager()+"\t"+link.getLink());
}
}
package com.qf.demo06;
public class Test {
public static void main(String[] args) {
//实例化打印机
Pager pa = new A3Pager();
Link l = new BlackLink();
Printer p = new Printer();
p.setPager(pa);
p.setLink(l);
p.print();
}
}
关键:使用多态的向上转型,new 引用父类对象类型的对象,然后将此对象作为参数传入方法。对象传入是一个地址,引用数据类型基本都是一个地址名,指向一个空间
四、类与接口 接口与接口之间的关系
1.类与类:只能单继承 多层继承 不支持多继承
2.类与接口:类可以实现单接口 也可以实现多接口
3.接口与接口:接口与接口可以单继承 也可以多继承 接口与接口之间只能继承用extends关键字,不能用implements关键字
例子:public interface Inner02 extends Inner,Inner01 {}
package com.qf.demo08;
public interface USBInterface {
void open();
void work();
void close();
}
package com.qf.demo08;
public class KeyBoard implements USBInterface {
@Override
public void open() {
System.out.println("打开键盘......");
}
@Override
public void work() {
System.out.println("正在撸键盘.....");
}
@Override
public void close() {
System.out.println("正在关闭键盘......");
}
}
package com.qf.demo08;
public class Mouse implements USBInterface {
@Override
public void open() {
System.out.println("正在开启.......");
}
@Override
public void work() {
System.out.println("正在瞎点......");
}
@Override
public void close() {
System.out.println("正在关闭........");
}
}
package com.qf.demo08;
public class NoteBook {
public void open(){
System.out.println("笔记本开启.....");
}
public void useUsb(USBInterface usb){
usb.open();
usb.work();
usb.close();
}
public void close(){
System.out.println("关机.......");
}
}
package com.qf.demo08;
public class Test {
public static void main(String[] args) {
//实例化笔记本对象
NoteBook note = new NoteBook();
note.open();
//实例化键盘的对象
USBInterface usb = new KeyBoard();
note.useUsb(usb);
//使用鼠标
USBInterface usb1= new Mouse();
note.useUsb(usb1);
note.close();
}
}
五、内部类(基本用不到看看就好)
1.概念:定义在类中的类 或者是定义在方法的类 就是内部类
2.分类:
成员内部类:普通成员内部类 私有内部类 静态内部类
局部内部类:定义在方法中的类
匿名内部类 没有名称的内部类
3.普通的成员内部类
位置:定义在类中 方法外
语法:
访问修饰符 class 外部类名 {
访问修饰符 class 内部类名{
}
}
说明:
A.内部类是可以访问外部类的私有的属性以及方法
B.外部类访问内部类的私有 必须实例化内部类对象才能访问
C.外部类以外的类访问内部类的资源 需要同外部类来实例化内部类对象
语法: 外部类的类名.内部类 对象名 = new 外部类的类名().new 内部类();
4.私有内部类
位置:定义在类中 方法外
语法:
访问修饰符 class 外部类名 {
private class 内部类名{
}
}
说明:
A.内部类是可以访问外部类的私有的属性以及方法
B.外部类访问内部类的私有 必须实例化内部类对象才能访问
C.外部类以外的类不能直接实例化内部类对象 但是可以通过外部类来调用其方法获取属性
5.静态内部类:
位置:定义在类中 方法外
语法:
访问修饰符 class 外部类名 {
static class 内部类类名{
}
}
说明:
A.静态内部类中方法只能获取外部类的静态资源
B.外部类访问静态内部类的资源 只能通过实例化对象来获取
C.外部类以外的类访问静态内部类的语法:
外部类.内部类 对象名 = new 外部类.内部类()
例子: OutClass.IntClass in = new OutClass.IntClass();
6.局部内部类
位置:定义在方法中
语法:
访问修饰符 返回值类型 方法名(){
class 类名 {
}
}
说明:
A.局部内部类只能间接进行调用内部类的资源
7.匿名内部类
位置:一般是定义在方法在方法的参数中
注意点:一般是与接口或者抽象类搭配的使用
匿名接口类 等于接口的实现类 匿名抽象类 等于抽象类的子类
成员内部类
package com.qf.demo09;
public class OutClass {
private int num=20;
public void showInfo(){
System.out.println("哈哈哈!我是外部类");
InClass in = new InClass();
in.show();
System.out.println(in.inNum);
}
public class InClass{
private int inNum=400;
public void show(){
System.out.println(num);
showInfo();
}
}
}
package com.qf.demo09;
public class Test {
public static void main(String[] args) {
// OutClass.InClass in = new OutClass().new InClass();
// in.show();
/* OutClass outClass = new OutClass();*/
}
}
代码局部内部类
package com.qf.demo12;
public class OutClass {
public void showInfo(){
class InnerClass{
private int num=20;
public void show(){
System.out.println("哈哈");
}
/* public void show(){
InnerClass in = new InnerClass();
in.showInfo();
}
*/
}
InnerClass in = new InnerClass();
in.show();
}
}
package com.qf.demo12;
public class Test {
public static void main(String[] args) {
OutClass outClass = new OutClass();
outClass.showInfo();
}
}
匿名内部类
package com.qf.demo13;
public class Test {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
}
});
showInfo(new Inner() {
@Override
public void show() {
}
});
show(new Inner01() {
@Override
public void showInfoInner01() {
System.out.println("dddd");
}
});
}
public static void showInfo(Inner inner){
inner.show();
}
public static void show(Inner01 inner01){
inner01.showInfoInner01();
}
}
六、面向对象思想的案例
父类 汽车类
package day10.demo;
public abstract class Car {
private String brand;
private String carNum;
private int dayRent;
public Car() {
}
public Car(String brand, String carNum, int dayRent) {
this.brand = brand;
this.carNum = carNum;
this.dayRent = dayRent;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getCarNum() {
return carNum;
}
public void setCarNum(String carNum) {
this.carNum = carNum;
}
public int getDayRent() {
return dayRent;
}
public void setDayRent(int dayRent) {
this.dayRent = dayRent;
}
public abstract double delChange(int days);
}
子类 轿车类
package day10.demo;
public class SmallCar extends Car{
private String type;
public SmallCar() {
}
public SmallCar(String brand, String carNum, int dayRent, String type) {
super(brand, carNum, dayRent);
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public double delChange(int days) {
if(days>7&&days<=30){
return 0.9;
}else if(days>30&&days<=150){
return 0.8;
}else if(days>150){
return 0.7;
}else {
return 1;
}
}
}
子类 客车类
package day10.demo;
public class Bus extends Car{
private int cheerNum;
public Bus() {
}
public Bus(String brand, String carNum, int dayRent, int cheerNum) {
super(brand, carNum, dayRent);
this.cheerNum = cheerNum;
}
public int getCheerNum() {
return cheerNum;
}
public void setCheerNum(int cheerNum) {
this.cheerNum = cheerNum;
}
@Override
public double delChange(int days) {
if(days>=3&&days<7){
return 0.9;
}else if(days>=7&&days<30){
return 0.8;
}else if(days>=30&&days<150){
return 0.7;
}else if(days>=150){
return 0.6;
} else {
return 1;
}
}
}
操作类
package day10.demo;
public class Player {
Car [] cars = new Car[8];
//初始化数组存储数据
public void init(){
cars[0] = new SmallCar("宝马","京NY28588",800,"X6");
cars[1] = new SmallCar("宝马","京CNY3284",600,"550i");
cars[2] = new SmallCar("别克","京NT37465",300,"林荫大道");
cars[3] = new SmallCar("别克","京NT96968",600,"GL8");
cars[4] = new Bus("金杯","京6566754",800,16);
cars[5] = new Bus("金龙","京8696997",800,16);
cars[6] = new Bus("金杯","京9696996",1500,34);
cars[7] = new Bus("金龙","京8696998",1500,34);
}
public Car findCar(String brand,String type,int cheerNum){
if(cars !=null && cars.length>0){
for (int i = 0; i < cars.length; i++) {
Car c = cars[i];
if(c instanceof SmallCar){
SmallCar b = (SmallCar) c;
if(brand.equals(b.getBrand())&&type.equals(b.getType())){
return b;
}
}else if(c instanceof Bus){
Bus b = (Bus) c;
if(brand.equals(b.getBrand())&&cheerNum == b.getCheerNum()){
return b;
}
}
}
}
return null;
}
}
测试类
package day10.demo;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Player p = new Player();
//面向对象思想就是将操作封装为一个操作类,类似手洗和洗衣机,将手洗所有操作封装为一个洗衣机类,
//需要洗衣服时就在测试类中new一个洗衣机类,调用洗衣机的方法,传入相应参数(衣服,洗衣液)等等
//面向过程就是在测试类中写所有操作,一步一步传参数
p.init();//调用方法,将数据填入数组
System.out.println("******欢迎使用租车系统*******");
System.out.println("1、轿车 2、客车");
Scanner sc = new Scanner(System.in);
System.out.println("请选择汽车类型");
int carNum = sc.nextInt();
//创建并初始化需要传入的参数,当符合条件在改变参数的值
String brand = "";
String type ="";
int cheerNum =0;
switch (carNum){
case 1:
System.out.println("请选择品牌:1、别克 2、宝马");
int brandNum = sc.nextInt();
switch (brandNum){
case 1:
brand ="别克";
System.out.println("请输入型号:1、林荫大道 2、GL8");
int typeNum = sc.nextInt();
switch (typeNum){
case 1:
type="林荫大道";
break;
case 2:
type="GL8";
break;
}
break;
case 2:
brand ="宝马";
System.out.println("请输入型号:1、X6 2、550i");
typeNum = sc.nextInt();
switch (typeNum){
case 1:
type="X6";
break;
case 2:
type="550i";
break;
}
break;
default:
System.out.println("输入错误");
break;
}
break;
case 2:
System.out.println("请选择品牌:1、金龙 2、金杯");
brandNum = sc.nextInt();
switch (brandNum){
case 1:
brand ="金龙";
System.out.println("请输入座位数:1、16座 2、34座");
int cheerNum1 = sc.nextInt();
switch (cheerNum1){
case 1:
cheerNum=16;
break;
case 2:
cheerNum=34;
break;
}
break;
case 2:
brand ="金杯";
System.out.println("请输入座位数:1、16座 2、34座");
cheerNum1 = sc.nextInt();
switch (cheerNum1){
case 1:
cheerNum=16;
break;
case 2:
cheerNum=34;
break;
}
break;
default:
System.out.println("输入错误");
break;
}
break;
default:
System.out.println("输入错误");
break;
}
Car c = p.findCar(brand,type,cheerNum);
System.out.println("请输入租借天数");
int days = sc.nextInt();
System.out.println("分配你的车牌号是"+c.getCarNum());
System.out.println("你应支付:"+c.getDayRent()*c.delChange(days)*days);
}
}
关键1: 面向对象思想就是将操作封装为一个操作类,例如手洗和洗衣机,将手洗所有操作封装为一个洗衣机类,需要洗衣服时就在测试类中new一个洗衣机类,调用洗衣机的方法,传入相应参数(衣服,洗衣液)等等
面向过程就是在测试类中写所有操作,一步一步写步骤传参数
关键2:分析出操作类,A.一般都要封装初始化填入数据,
B.找到实现功能的关键,
本例就是要计算总租金,只要找到车,就能找到其他信息,将车作为主键绑定其他信息,
为什么车能当主键,因为车类是父类对象,利用多态向下转型可以获取绑定信息,
怎么找,通过用户的操作需求来分析,用户需要选择车的品牌、型号、座位数来选择车类,所以我们也通过品牌、型号、座位数来锁定车,在测试类中创建并初始化需要传入的参数(品牌、型号、座位数),当符合条件时(即用户做出选择操作时)在改变参数的值锁定具体的车