一 抽象类
1.由来
父类中的方法,如果所有子类都要重写,那么此时父类的方法体就失去了意义
那么我们可以把方法体去掉,只留方法的声明,这种只有方法声明没有方法实现的方法称为
抽象方法
含有抽象方法的类一定是抽象类
子类如果继承了抽象类,那么必须重写抽象类中所有的抽象方法,否则子类还是一个抽象类
2.抽象方法的格式;
public abstract 返回值类型 方法名(参数列表);
3.抽象类的格式:
public abstract class 类名{....}
4.注意事项:
a.抽象类是不能创建对象的!
b.抽象类是有构造方法,是给子类的构造方法调用的
(子类所有构造中都有默认使用super()调用父类的无参构造)
c.抽象类不一定包含抽象方法,但是包含抽象方法的类一定是抽象类
(抽象类可以有也可以没有抽象方法)
d.抽象类子类 必须 重写所有抽象方法,否则子类还是一个抽象类
5.抽象类中可以定义的成员
成员变量,成员方法,构造方法,抽象方法
6."抽象类"类型的多态形式
父类类型 变量名 = new 子类类型();
抽象类型类 变量名 = new 子类类型();
二.接口
1.什么是接口
专业:接口是方法的集合(接口中只有方法,没有普通的成员变量)
通俗:接口是一种极端的抽象类(在JDK1.7之前 所有的方法必须都是抽象方法)
(在JDK1.8时增加默认方法,静态方法)
(在JDK1.9时增加私有方法)
2.定义接口的格式:
类: 使用关键字 class
枚举: 使用关键字enum
抽象类:使用abstract class
接口: 使用关键字interface
格式:
public interface 接口名{
//抽象方法(JDK1.7)
public abstract 返回值类型 方法名(参数列表);
//默认方法(JDK1.8)
public default 返回值类型 方法名(参数列表){
}
//静态方法(JDK1.8)
public static 返回值类型 方法名(参数列表){
}
//私有方法(忽略)
private 返回值类型 方法名(参数列表){
}
}
3.接口的使用
a.接口也是不能创建对象的
实现类 实现(implements) 接口 (相当于子类 继承 抽象类)
public class 实现类 implements 接口{
a.实现类需要重写接口中所有的抽象方法,否则实现类变成一个抽象类
b.实现类可以选择性重写接口中默认方法
c.实现类对于接口的静态方法没有重写这种说法
d.实现类对于接口的私有方法没有重写这种说法
}
4.接口的多实现
一个实现类 可以 实现多个接口
格式:
public class 实现类 implements 接口1,接口2,接口3....{
//1.必须重写所有接口中的所有抽象方法
//2.可以选择性重写所有接口中的任何默认方法
//3.实现类对于接口的静态方法没有重写这种说法
//4.实现类对于接口的私有方法没有重写这种说法
}
5.有同名的方法的接口多实现
public class 实现类 implements 接口1,接口2,接口3....{
//1.如果多个接口有同名的抽象方法,实现类只需要重写一次
//2.如果多个接口中有同名的默认方法,实现类必须重写一次
//3.静态方法同名,没有问题,哪个接口调用静态方法,调用的就是那个接口中静态方法
//4.私有方法同名,更加没有问题,私有方法只能在当前接口中使用(如果你写私有方法和静态方法的时候报错了,注意看 JDK版本)
}
6.继承和实现
实际中,一个类 继承 一个父类,同时实现多个接口
格式:
public class 类名 extends 父类 implements 接口1,接口2...{
//如果父类和接口都有相同的抽象方法,只需要写一次即可
//父类有一个方法和接口的默认方法重名,可以不重写,父类方法的优先级高
}
7.接口和接口之间多继承(了解即可)
格式:
public interface 子接口 extends 父接口1,父接口2...{
a.如果多个父接口中有相同抽象方法,子接口只有一个抽象方法
b.如果多个父接口中有相同的默认方法,子接口必须重写一次
c.私有和静态不需要关注
}
public class 类名 implements 子接口{
}
相当于
public class 类名 implements 父接口1,父接口2,...{
}
8.接口的其他成员
a.接口中无法定义变量,但是可以定义常量
public static final 数据类型 常量名 = 值;
三个修饰符可写可以不写,默认就有!!!!
b.接口中没有构造方法,也不能创建对象
c.接口中,没有静态代码块。
三.练习
一.
1:所有动物都有姓名,年龄;(成员变量要求私有)
2:所有动物都有自我介绍的方法(使用 show 方法表示),但是具体描述的内容不一样;
狗类描述内容: 我叫 xxx,今年 xxx 岁了,我的病症是感冒;
猫类描述内容: 我叫 xxx,今年 xxx 岁了,我的病症是发烧;
3:编写测试类,测试猫类和狗类的 show 方法;
效果:我叫阿强,今年3我的病症是感冒
我叫阿花,今年2我的病症是发烧
public abstract class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
abstract void show();
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 "Animal{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
------------------------------------------------------------------------------------
public class Cat extends Animal {
public Cat() {
}
public Cat(String name, int age) {
super(name, age);
}
@Override
void show() {
System.out.println("我叫"+this.getName()+",今年"+this.getAge()+"我的病症是发烧");
}
}
-------------------------------------------------------------------------------------
public class Dog extends Animal {
public Dog(){
}
public Dog(String name,int age){
super(name,age);
}
@Override
void show() {
System.out.println("我叫"+this.getName()+",今年"+this.getAge()+"我的病症是感冒");
}
}
---------------------------------------------------------------------------------------
public class TestDemo {
public static void main(String[] args) {
Dog d = new Dog("阿强",3);
d.show();
new Cat("阿花",2).show();
}
}
二.计算正方形和圆形的面积和周长
public abstract class Figure {
//static能和abstract同时使用,
//1.被static修饰的方法在与无static修饰的方法在内存中的位置不同
//2.被static修饰的方法、变量等属于类,不是给子类来继承的。
public abstract double area();
public abstract double Perimeter();
}
--------------------------------------------------------------------------------
public class Yuan extends Figure {
private double r;
public Yuan(double r) {
this.r = r;
}
public Yuan() {
}
public double getR() {
return r;
}
public void setR(double r) {
this.r = r;
}
@Override
public double area() {
return Math.PI*r*r;
}
@Override
public double Perimeter() {
return 2*Math.PI*r;
}
}
------------------------------------------------------------------------------------
public class Zheng extends Figure{
private double Long;
public Zheng() {
}
public double getLong() {
return Long;
}
public void setLong(double aLong) {
Long = aLong;
}
public Zheng(double aLong) {
this.Long = aLong;
}
@Override
public double area() {
return this.Long*4;
}
@Override
public double Perimeter() {
return this.Long*Long;
}
}
-----------------------------------------------------------------------------------
public class TestDome2 {
public static void main(String[] args) {
Zheng square = new Zheng(3.14);
System.out.println("正方形的周长是:"+square.Perimeter());
System.out.println("正方形的周长是:"+square.area());
Yuan circular = new Yuan(3.14);
System.out.println("正方形的周长是:"+circular.Perimeter());
System.out.println("正方形的周长是:"+circular.area());
}
}
三.自定义一个接口,包含默认方法 methodA 和抽象方法 methodB,通过实现类的对象这两个方法;
效果:接口中的默认方法执行了...
实现类重写的方法执行了...
public interface Father {
public default void methodA(){
System.out.println("接口中的默认方法执行了...");
}
public abstract void merhodB();
}
---------------------------------------------------------------------
public class MyClass implements Father {
@Override
public void merhodB() {
System.out.println("实现类重写的方法执行了...");
}
public static void main(String[] args) {
MyClass test= new MyClass();
test.methodA();
test.merhodB();
}
}
四.使用实现类对象通过默认方法调用接口中的静态方法完成打印10 次指定字符串的功能;
效果:CCC CCC CCC CCC CCC CCC CCC CCC CCC CCC
public interface FaterInter04 {
default void print(String AAA){
//1 java类中的静态方法 只能调用类中的静态方法;
//2 java类中的非静态方法可以调用类中的非静态方法和静态方法
printAAA(AAA);
}
static void printAAA(String AAA){
for (int i = 0; i < 10; i++) {
System.out.print(AAA+" ");
}
}
}
----------------------------------------------------------------------------
public class Zi04 implements FaterInter04 {
}
----------------------------------------------------------------------------
public class TestDome04 {
public static void main(String[] args) {
Zi04 zi04= new Zi04();
zi04.print("CCC");
}
}
五.
1:创建一个动物类,包含私有的姓名,getter/setter,构造方法,一个抽象的吃饭方法;
2:编写猫类和狗类,继承动物类,描述猫吃鱼,狗吃骨头,并以多态的
形式调用吃饭的方法;
效果:阿强是一只猫,吃鱼
阿花是一只狗,吃骨头
public abstract class Animal05 {
private String name;
public abstract String eat();
public Animal05(String name) {
this.name = name;
}
public Animal05() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
-----------------------------------------------------------------------------
public class Cat05 extends Animal05{
@Override
public String eat(){
return "吃鱼";
}
public Cat05(String name){
super(name);
}
}
------------------------------------------------------------------------------
public class Dog05 extends Animal05 {
@Override
public String eat() {
return "吃骨头";
}
public Dog05(String name) {
super(name);
}
public Dog05() {
}
}
-------------------------------------------------------------------------------
public class TestDemo05 {
public static void main(String[] args) {
Animal05 animal = new Dog05("阿花");
if(animal instanceof Dog05){
Dog05 d =(Dog05)animal;
System.out.println(d.getName()+"是一只狗,"+d.eat());
} else{
Cat05 c = (Cat05)animal;
System.out.println(c.getName()+"是一只猫,"+c.eat());
}
}
}
六.模拟购物车的添加商品,然后展示购物车详情的功能;
商品包含:商品名称,商品价格;
效果:商品{名字='小米8', 价格=2888.0}
商品{名字='锤子2s', 价格=2888.0}
商品{名字='华为10', 价格=2888.0}
public class article {
private String name;
private double price;
public article(String name, double price) {
this.name = name;
this.price = price;
}
public article() {
}
@Override
public String
toString() {
return "商品{" +
"名字='" + name + '\'' +
", 价格=" + price +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
---------------------------------------------------------------------------
import java.util.ArrayList;
public class Cart {
ArrayList<article> list = new ArrayList<>();
public static void main(String[] args) {
new Cart().add();
}
public void add(){
list.add(new article("小米8",2888.0));
list.add(new article("锤子2s",2888.0));
list.add(new article("华为10",2888.0));
print();
}
public void print(){
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i)); //重写了toString
}
}
}