面向对象——多态、抽象、包、接口
A.多态
1.多态含义,使用
什么是多态:
多态顾名思义即为多种形态的意思
Java中多态的含义:
-
发送消息给某个对象,让这个对象自行决定采用哪种行为响应这个消息
-
子类对象的引用赋值给父类引用变量来实现动态的方法调用
-
Java中形成多态的前提:
继承
重写
向上转型
多态 :多种形态。
类型自动向上转换。
子类对象赋值给父类引用。
一旦发生类型向上转换,只能调用父类继承下来的方法。
//多态 :多种形态
//类型自动向上转换
//子类对象赋值给父类引用
//一旦发生类型向上转换,只能调用父类继承下来的方法。
Person per_1 = new Student("Tom",18,"男","1002",2,89);
String s = per_1.toString();
System.out.println(s);
// per_1.study(); //不能调用,因为Study是子类 的方法。
per_1.ear();
2.题目(继承、方法重写、多态)
设计一个形状类Shape,方法:求周长和求面积。
形状类的子类:Rect(矩形),Circle(圆形)。
Rect类的子类:Square(正方形)。
不同的子类会有不同的计算周长和面积的方法。
Shape类:
package com.mianxiangduixiang.duotai.AreaAndPer;
public class Shape {
public void area(){
}
public void per(){
}
public Shape(){
}
}
Rect类:
package com.mianxiangduixiang.duotai.AreaAndPer;
public class Rect extends Shape{
private int width;
private int height;
//方法重写
@Override
public void area(){
double are = this.height * this.width;
System.out.println("矩形面积为:"+are);
}
@Override
public void per() {
double pe = (this.height + this.width) * 2;
System.out.println("矩形周长为:"+pe);
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public Rect() {
}
public Rect(int width, int height) {
this.width = width;
this.height = height;
}
}
Ciecle类:
package com.mianxiangduixiang.duotai.AreaAndPer;
public class Ciecle extends Shape{
private int r;
public static final double PI = 3.14;
@Override
public void area() {
double are = PI * this.r * this.r;
System.out.println("圆面积为:"+are);
}
@Override
public void per() {
double pe = 2*this.r*PI;
System.out.println("圆周长为:"+pe);
}
public int getR() {
return r;
}
public void setR(int r) {
this.r = r;
}
public Ciecle() {
}
public Ciecle(int r) {
this.r = r;
}
}
Student类(多态用法):
package com.mianxiangduixiang.duotai.AreaAndPer;
public class Studeng {
public Studeng() {
}
public void getAreaAndPerE(Shape shape){
shape.area();
shape.per();
}
}
测试类;
package com.mianxiangduixiang.duotai.AreaAndPer;
public class Testmain {
public static void main(String[] args) {
/**
* 设计一个形状类Shape,方法:求周长和求面积
* 形状类的子类:Rect(矩形),Circle(圆形)
* Rect类的子类:Square(正方形)
* 不同的子类会有不同的计算周长和面积的方法*/
Ciecle cie = new Ciecle(5);
Rect re = new Rect(10,15);
Studeng st = new Studeng();
st.getAreaAndPerE(cie);
st.getAreaAndPerE(re);
}
}
3.作用
- 提高代码的可重用性。
- 降低模块之间的耦合度。
public static void getAreaAndPerE(Shape shape){
shape.area();
shape.per();
}
Ciecle cie = new Ciecle(5);
Rect re = new Rect(10,15);
// Studeng st = new Studeng();
Studeng.getAreaAndPerE(cie);
Studeng.getAreaAndPerE(re);
B.抽象
- 形状类Shape需要提供用于计算面积和周长的方法,但是形状本身没有被确定,那么计算周长和面积的方法就无法确定,此时我们就需要使用抽象类和抽象方法。
- 由于Shape类计算周长和面积的方法无法确定,那么就可以将这样的方法声明为抽象的,以便在具体的子类中进行实现。
抽象方法的声明 [修饰符] abstract 返回值类型 方法名([参数列表]);
注意:因为抽象方法无法确定具体执行的功能,所有抽象方法没有方法体,需要在小括号后加上分号
抽象:不具体。
当某一个方法的方法体具体执行过程不确定的时候,可以把这个方法生命成抽象方法。
如果一个类的某些功能比较抽象或者无法在本类中具体实现,可以将这个类声明为抽象的,那么这些抽象或者无法具体实现的功能可以在子类中完成。
抽象类的语法
[修饰符] abstract class 类名 [extends 父类名]{类体}
- 抽象类和普通类除了使用abstract修饰外和普通的类相似
- 抽象类中可以没有抽象方法
- 但是一旦某个有抽象方法,那么这个类必须被声明为抽象类
//抽象中可以有属性
因为抽象类不是一个具体的类,所以无法实例化,但是抽象类可以用于声明对象。
抽象类可以被继承,在子类中实现抽象类的所有抽象方法,以达到抽象类的具体化
具体化后的子类方法就可以用来创建对象了。
//抽象方法,不需要方法体
//如果一个类中有抽象方法,则该类为抽象类,使用abstart修饰。
public abstract class Shapepe {
public abstract void aa();
}
//抽象
//当某一个方法的方法体具体执行过程不确定的时候,可以把这个方法生命成抽象方法
//抽象方法,不需要方法体
//如果一个类中有抽象方法,则该类为抽象类,使用abstart修饰。
// public abstract void are();
//抽象类,可以没有抽象方法
//抽象类不可以创建对象,但是可以作为引用
//抽象类的子类,必需要重写父类的抽象方法。否则子类需要声明成抽象类。
//init,instance,初始化,实例化
C.接口interface
1.接口的定义
在软件工程中,经常将一个大的项目分由不同的开发小组共同开发,各个小组的开发工作是并行的。在很多时候,对于不同小组的程序员来说,清楚地说明各自的软件如何相互作用,并就此达成统一“约定”是很重要的。这种情况下,每一小组都可以在对其他小组怎么编写代码一无所知的情况下,就能编写自己的代码,并且各自小组编写的代码能很好的协同工作。接口就是这样的“约定”。
在Java中接口不仅仅是程序开发过程中“约定”,更是更加抽象化的抽象类
接口的定义
[修饰符] interface 接口名{[常量];[抽象方法];}
2.接口的实现
接口的实现:
定义类时通过implements关键字实现接口
接口实现的语法
[修饰符] class 类名 [extends 父类名] [implements 接口1,接口2,……]{类体部分}
一个类可以实现多个接口,从而解决了Java单继承的缺点。
//继承和多实现
public class Circle extends Object implements Shape,A{
}
3.接口的继承
- 在Java中类之间的继承关系是单继承,也就是说一个类有且只能有一个父类。
- 而Java中的接口实现了多继承,也就是说一个接口可以有多个父接口
接口和接口之间多继承:
public interface C extends A,B{
public void c();
}
4.接口的作用
- 提高程序的重用性
- 提高程序的可扩展性
- 降低程序的耦合度
- 实现了多继承
5.代码实现
public interface Shape {
//接口:接口中的方法,都是抽象方法
//接口中的方法可以省略abstract关键字,默认就是抽象方法
//接口中的方法默认是Public
//接口中能有属性。
//子类使用 implement 实现接口,可以多实现
public final static int A = 23;
public int W = 1;
//接口中的属性都是静态常量
//可以省略final 和 static 修饰符 public 也可以省略
//一般都不省略,可以清晰的直观的看明白属性
//不需要创建构造方法
public abstract void area();
public abstract void perimeter();
public void a();
void b();//不写默认也是public
//新版本李米娜接口可以有默认方法,有方法体,要的defaule 修饰,就是一个普通方法,不能直接用类名调用。
default void sumoi(){
System.out.println("我是接口!");
}
}
public class Circle implements Shape{
@Override
public void area() {
}
@Override
public void perimeter() {
}
@Override
public void a() {
}
@Override
public void b() {
}
}
public class main {
public static void main(String[] args) {
// Shape.A= 10;//不能赋值给接口中的属性赋值
System.out.println(Shape.A);//可直接用类名调用
Shape sha = new Circle();
sha.a();
}
}
instanceof
D.包的导入
什么是包
-
包是Java用于提供访问保护和命名空间管理的方式
-
简单的理解,包就是用来将Java中类和接口等进行分类管理的工具,类似于操作系统中的目录
包的声明
- package 包名;
- 包名的前半部分一般使用倒置的域名,后半部分一般采用该包下类分类名(或者功能名),如:package com.sina.util;
- 包的声明必须是整个类文件的第一行语句
package com.mianxiangduixiang;
import jdk.nashorn.internal.runtime.regexp.joni.constants.internal.OPCode;
instanceof运算符
用于判断一个对象是不是某个类的实例
public void getShapeAreaAndPerimeter(Shape shape) {
if (shape == null) {
return;
}
if (shape instanceof Circle) {
Circle ci = (Circle) shape;
ci.area();
ci.perimeter();
} else if (shape instanceof Rect) {
Rect re = (Rect) shape;
re.perimeter();
re.area();
}
}
一旦需要使用另外一个包中的类时,需要将该类导入到当前类中,如需要在程序中使用java.util包下的Scanner类,需要将给类先导入到使用的类中
类导入的语法
import 包名.类名;
或者 import 包名.*;
接口:出现在父类,在父类里面都不知道是什么的时候。
抽象类:部分知道,部分不知道。
总练习题(面向对象各个知识点的融合):
Address类:
package com.mianxiangduixiang.jiekou.BigCramre;
public class Address {
private String sheng ;
private String shi;
private String xian;
public String getSheng() {
return sheng;
}
public void setSheng(String sheng) {
this.sheng = sheng;
}
public String getShi() {
return shi;
}
public void setShi(String shi) {
this.shi = shi;
}
public String getXian() {
return xian;
}
public void setXian(String xian) {
this.xian = xian;
}
public Address() {
}
public Address(String sheng, String shi, String xian) {
this.sheng = sheng;
this.shi = shi;
this.xian = xian;
}
}
Circle类:
package com.mianxiangduixiang.jiekou.BigCramre;
public class Circle implements Shape{
public static final double PI = 3.14;
private int redius;
@Override
public void area() {
double mianji = PI * this.redius * this.redius;
System.out.println("圆的面积为:"+mianji);
}
@Override
public void perimeter() {
double zhouchang = PI*2*this.redius;
System.out.println("圆的周长为:"+zhouchang);
}
public int getRedius() {
return redius;
}
public void setRedius(int redius) {
this.redius = redius;
}
public Circle() {
}
public Circle(int redius) {
this.redius = redius;
}
}
抽象类Crmera:
package com.mianxiangduixiang.jiekou.BigCramre;
public abstract class Crmera implements TakePhoto {
private String brand;
private String price;
private String color;
@Override//重写方法
public void takephoto() {
System.out.println("照相机拍照");
}
//抽象方法
public abstract void focus();//聚焦
public void charge() {
System.out.println("照相机可以更换电池哦!");
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Crmera() {
}
public Crmera(String brand, String price, String color) {
this.brand = brand;
this.price = price;
this.color = color;
}
}
DigitCamera类:
package com.mianxiangduixiang.jiekou.BigCramre;
public class DigitCamera extends Crmera{
private String space;
public void luxiang(){
System.out.println("数码相机可以录像哦!");
}
public String getSpace() {
return space;
}
public void setSpace(String space) {
this.space = space;
}
@Override
public void focus() {
System.out.println("我也有聚焦!");
}
@Override
public void takephoto() {
System.out.println("数码拍照");
}
public DigitCamera() {
}
public DigitCamera(String brand, String price, String color, String space) {
super(brand, price, color);
this.space = space;
}
}
Oldphone类:
package com.mianxiangduixiang.jiekou.BigCramre;
public class OldPhone extends Phone{
private String keyBord;//键盘
public void kaiHeTao(){
System.out.println("我可以直接砸核桃!");
}
public String getKeyBord() {
return keyBord;
}
public void setKeyBord(String keyBord) {
this.keyBord = keyBord;
}
@Override
public void call() {
System.out.println("老年机的打电话方式!");
}
public OldPhone() {
}
public OldPhone(String brand, String price, String color, String keyBord) {
super(brand, price, color);
this.keyBord = keyBord;
}
}
Phone抽象类类:
package com.mianxiangduixiang.jiekou.BigCramre;
public abstract class Phone {
private String brand;//品牌
private String price;//价格
private String color;//颜色
//抽象方法 打电话
public abstract void call();
public void sendMsg(){
System.out.println("我是Phone中的方法!");
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Phone() {
}
public Phone(String brand, String price, String color) {
this.brand = brand;
this.price = price;
this.color = color;
}
}
Rect类:
package com.mianxiangduixiang.jiekou.BigCramre;
public class Rect implements Shape{
private int width;
private int height;
@Override
public void area() {
double mianji = this.width * this.height;
System.out.println("矩形面几=积 为"+mianji);
}
@Override
public void perimeter() {
double zhouchang = (this.height + this.width)*2;
System.out.println("矩形周长为"+zhouchang);
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public Rect(int width, int height) {
this.width = width;
this.height = height;
}
public Rect() {
}
}
接口Shape:
package com.mianxiangduixiang.jiekou.BigCramre;
public interface Shape {
public void area();//面积方法
public void perimeter();//周长方法
}
SingleCamera类:
package com.mianxiangduixiang.jiekou.BigCramre;
public class SingleCamera extends Crmera{
private String lensNum;
public void changeLens(){
System.out.println("我是SingleCamera中的方法哦!");
}
public String getLensNum() {
return lensNum;
}
public void setLensNum(String lensNum) {
this.lensNum = lensNum;
}
@Override
public void focus() {
System.out.println("单反聚焦!");
}
@Override
public void takephoto() {
System.out.println("单反拍照");
}
public SingleCamera() {
}
public SingleCamera(String brand, String price, String color, String lensNum) {
super(brand, price, color);
this.lensNum = lensNum;
}
}
SmartPhone类:
package com.mianxiangduixiang.jiekou.BigCramre;
public class SmartPhone extends Phone implements TakePhoto{
private String sys;//系统
public void surfInt(){
System.out.println("智能手机网上冲浪!");
}
public String getSys() {
return sys;
}
public void setSys(String sys) {
this.sys = sys;
}
@Override
public void call() {
System.out.println("智能手机打电话!");
}
@Override
public void takephoto() {
System.out.println("手机可以拍照哦!");
}
public SmartPhone() {
}
public SmartPhone(String brand, String price, String color, String sys) {
super(brand, price, color);
this.sys = sys;
}
}
Student类:
package com.mianxiangduixiang.jiekou.BigCramre;
import com.mianxiangduixiang.duotai.AreaAndPer.Ciecle;
import java.util.Arrays;
public class Student {
private String name;
private int age;
private Address add;
public void stuTakePhoto(TakePhoto takePhoto) {
if (takePhoto == null) {
return;
}
takePhoto.takephoto();
}
public void stuCall(Phone phone) {
if (phone == null) {
return;
}
phone.call();
phone.sendMsg();
}
public void sortArr(int[] arr, String str) {
for (; ; ) {
if (str.equals("asc")) {
for (int i = 1; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
break;
} else if (str.equals("desc")) {
for (int i = 1; i < arr.length - 1; i++) {
for (int j = 0; j < arr.length - i; j++) {
if (arr[j] < arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
System.out.println(Arrays.toString(arr));
break;
}else{
System.out.println("输入有误!重新输入");
}
}
}
public void getShapeAreaAndPerimeter(Shape shape) {
if (shape == null) {
return;
}
if (shape instanceof Circle) {
Circle ci = (Circle) shape;
ci.area();
ci.perimeter();
} else if (shape instanceof Rect) {
Rect re = (Rect) shape;
re.perimeter();
re.area();
}
}
public Address getAdd() {
return add;
}
public void setAdd(Address add) {
this.add = add;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", add=" + add +
'}';
}
public Student() {
}
public Student(String name, int age, Address add) {
this.name = name;
this.age = age;
this.add = add;
}
}
接口Takephoto:
package com.mianxiangduixiang.jiekou.BigCramre;
public interface TakePhoto {
public void takephoto();
}
测试类:
package com.mianxiangduixiang.jiekou.BigCramre;
import jdk.nashorn.internal.runtime.regexp.joni.constants.internal.OPCode;
public class Main {
public static void main(String[] args) {
Shape sha = new Circle(5);
Shape sha_1 = new Rect(15,68);
//创建对象
Circle c = new Circle(3);
Rect r = new Rect(15,89);
OldPhone op = new OldPhone();
SmartPhone sm = new SmartPhone();
SingleCamera sing = new SingleCamera();
DigitCamera dig = new DigitCamera();
Address address = new Address("河北","zhangjiajie","cehsi");
Student stu = new Student("张三",18,address);
stu.stuTakePhoto(sm);//拍照
stu.stuTakePhoto(sing);
stu.stuCall(op);//打电话
stu.stuCall(sm);
//面积周长
sha.area();
sha.perimeter();
sha_1.perimeter();
sha_1.area();
//输出信息
stu.getShapeAreaAndPerimeter(r);
String s = stu.toString();
System.out.println(s);
//排序
int[] a = {52,58,2,98,7,6,59,99};
stu.sortArr(a,"asc");//正序
stu.sortArr(a,"desc");//倒序
//求面积周长
Circle cie = new Circle(6);
Rect re = new Rect(15,25);
stu.getShapeAreaAndPerimeter(re);
stu.getShapeAreaAndPerimeter(cie);
}
}