为什么要用抽象类,当子类要继承中父类的成员方法时,如果子类就是不重写怎么办?或者说父类时一个人写的 子类又是另外一个人写的那个人不知道要重写那该怎么办?这里就可以运用抽象类来强制对方重写子类中的成员方法了
抽象方法:
将共性的行为(方法)抽到父类之后.由于每一个子类执行的内容是不一样的,所以,在父类中不能确定具体的方法体.该方法就定义为抽象方法
抽象类:如果一个类中存在抽象方法,那么该类就必须声明为抽象类.
抽象类和抽象方法的定义格式
抽象方法的定义格式:
public abstract 返回值类型 方法名(参数列表);
抽象类的定义格式:
public abstract class 类名{}
抽象类和抽象方法的注意事项
抽象类不能实例化
抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
可以有构造方法
抽象类的子类:要么重写抽象类中的所有抽象方法 要么是抽象类
Person类:
public abstract class Person {
private String name;
private int age;
//抽象类中的构造方法的作用:当创建子类的时候,给属性赋值.
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
public abstract void work();
}
学生类:
public class Student extends Person{
public Student(){}
public Student(String name,int age){
super(name,age);
}
@Override
public void work(){
System.out.println("学生的工作是学习");
}
}
老师类:
public abstract class Teacher extends Person{
}
编写带有抽象类的标准Javabean类
青蛙frog 属性:名字,年龄 行为:吃虫子,喝水
狗Dog 属性:名字,年龄 行为:吃骨头,喝水
山羊Sheep 属性:名字,年龄 行为:吃草,喝水
这里的吃就可以设计成一个抽象方法
public abstract class Animal {
private String name;
private int age;
public Animal() {
}
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
public void drink(){
System.out.println("动物在喝水");
}
public abstract void eat();
}
public class Dog extends Animal{
public Dog() {
}
public Dog(String name, int age) {
super(name, age);
}
@Override
public void eat(){
System.out.println("狗吃骨头");
}
}
public class Frog extends Animal{
public Frog() {
}
public Frog(String name, int age) {
super(name, age);
}
@Override
public void eat(){
System.out.println("青蛙在吃虫子");
}
}
public class Sheep extends Animal{
public Sheep() {
}
public Sheep(String name, int age) {
super(name, age);
}
@Override
public void eat(){
System.out.println("山羊在吃草");
}
}
为什么有接口?
Animal类:
public abstract class Animal {
private int age;
private String name;
public Animal(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Animal(){
}
public abstract void eat();
}
Dog类:
public class Dog extends Animal implements swim{
public Dog(int age, String name) {
super(age, name);
}
public Dog() {
}
@Override
public void eat() {
System.out.println("狗吃骨头");
}
@Override
public void swim() {
System.out.println("狗刨");
}
}
Rabbit类:
public class Rabbit extends Animal{
public Rabbit(int age, String name) {
super(age, name);
}
public Rabbit() {
}
@Override
public void eat() {
System.out.println("兔子在吃胡萝卜");
}
}
Frog类:
public class Frog extends Animal implements swim{
public Frog(int age, String name) {
super(age, name);
}
public Frog() {
}
@Override
public void eat() {
System.out.println("青蛙在吃虫子");
}
@Override
public void swim() {
System.out.println("青蛙在蛙泳");
}
}
游泳接口:
public interface swim {
public abstract void swim();
}
Test类:
public class Test {
public static void main(String[] args) {
//创建对象
Frog f =new Frog(1,"yjy");
System.out.println(f.getName()+", "+f.getAge());
f.eat();
f.swim();
Rabbit r =new Rabbit(2,"bb");
System.out.println(r.getName()+", "+r.getAge());
r.eat();
}
}
接口中成员的特点:
成员变量:只能是常量 默认修饰符:public static final
构造方法:没有
成员方法:只能是抽象方法 默认修饰符:public abstract
JDK7以前:接口中只能定义抽象方法
接口和类之间的关系
类和类的关系
继承关系,只能单继承,不能多继承,但是可以多层继承
类和接口的关系
实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
接口1:
public interface Inter1 {
public abstract void method1();
public abstract void method2();
public abstract void method3();
}
接口2:
public interface Inter2 {
public abstract void method4();
public abstract void method5();
public abstract void method6();
}
类:
public class InterImpl implements Inter1,Inter2{
//如果有重名的方法 只需要重写一次就行了
@Override
public void method1() {
System.out.println("method1");
}
@Override
public void method2() {
System.out.println("method2");
}
@Override
public void method3() {
System.out.println("method3");
}
@Override
public void method4() {
System.out.println("method4");
}
@Override
public void method5() {
System.out.println("method5");
}
@Override
public void method6() {
System.out.println("method6");
}
}
接口和接口的关系
继承关系,可以单继承,也可以多继承
细节:如果实现类实现了最下面的子接口,那么就需要重写所有的抽象方法
public interface Inter1 {
public abstract void method1();
}
public interface Inter2 {
public abstract void method2();
}
public interface Inter3 extends Inter1,Inter2{
public abstract void method3();
}
public class InterImpl implements Inter3{
@Override
public void method1() {
}
@Override
public void method2() {
}
@Override
public void method3() {
}
}
//因为现在不行让外界去直接创建人的对象
//因为直接创建顶层人的对象是没有意义的
//所以就把他写为抽象的
public abstract class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
}
public abstract class Coach extends Person{
public Coach() {
}
public Coach(String name, int age) {
super(name, age);
}
public abstract void teach();
}
public abstract class Sporter extends Person{
public Sporter() {
}
public Sporter(String name, int age) {
super(name, age);
}
public abstract void study();//为什么要写成抽象的 因为乒乓球和打篮球学的东西不一样
}
public class PingPongSporter extends Sporter implements English{
public PingPongSporter() {
}
public PingPongSporter(String name, int age) {
super(name, age);
}
@Override
public void speakEnglish() {
System.out.println("乒乓球运动员在说英语");
}
@Override
public void study() {
System.out.println("乒乓球运动员在学习如何打乒乓球");
}
}
public class PingPongCoach extends Coach implements English{
public PingPongCoach() {
}
public PingPongCoach(String name, int age) {
super(name, age);
}
@Override
public void teach() {
System.out.println("乒乓球教练正在教如何打乒乓球");
}
@Override
public void speakEnglish() {
System.out.println("乒乓球教练在说英语");
}
}
public class BasketballSporter extends Sporter {
public BasketballSporter() {
}
public BasketballSporter(String name, int age) {
super(name, age);
}
@Override
public void study() {
System.out.println("篮球运动员在学习如何打篮球");
}
}
public class BasketballCoach extends Coach{
public BasketballCoach() {
}
public BasketballCoach(String name, int age) {
super(name, age);
}
@Override
public void teach() {
System.out.println("篮球教练正在教如何打篮球");
}
}
public class Test {
public static void main(String[] args) {
PingPongSporter pps=new PingPongSporter("刘siwen",23);
System.out.println(pps.getName()+", "+pps.getAge());
pps.study();
pps.speakEnglish();
}
}
多学三招:
1.JDK8开始接口中新增的方法
2.接口的应用
3.适配器设计模式
JDK8开始接口中新增的方法
JDK以前:接口中只能定义抽象方法
JDK8的新特性:接口中可以定义有方法体的方法.(默认,静态)
JDK9的新特性:接口中可以定义私有方法.
public interface InterA {
public abstract void method();
public default void show(){
System.out.println("InterA接口中的默认方法 ---show");
}
}
public interface InterB {
public default void show(){
System.out.println("InterB接口中的默认方法 ---show");
}
}
public class InterImpl implements InterA ,InterB{
@Override
public void method() {
System.out.println("实现类重写的抽象方法");
}
@Override
public void show() {
System.out.println("重写接口中的默认方法");
}
}
public class Test {
public static void main(String[] args) {
InterImpl ii =new InterImpl();
ii.method();
ii.show();
}
}
public interface InterA {
public static void show(){
System.out.println("Inter接口中的静态方法");
}
public abstract void method();
}
public class InterImpl implements InterA {
@Override
public void method() {
System.out.println("实现类重写的抽象方法");
}
//这个不叫重写
public static void show(){
System.out.println("实现类的静态方法");
}
}
public class Test {
public static void main(String[] args) {
//调用接口中的静态方法
InterA.show();
//调用实现类的静态方法
InterImpl.show();
//子类把父类继承下来的虚方法表里面的方法进行了覆盖了,这才叫重写.
}
}
public interface InterA {
// public default void show1(){
// System.out.println("show1方法开始执行了");
// show3();
// }
// public default void show2(){
// System.out.println("show2方法开始执行了");
// show3();
// }
public default void show1(){
System.out.println("show1方法开始执行了");
show4();
}
public default void show2(){
System.out.println("show2方法开始执行了");
show4();
}
//普通的私有方法,给默认方法服务的
private void show3(){
System.out.println("记录程序在运行过程中的各种细节,这里有100行代码");
}
//静态的私有方法,给静态方法服务的
private void show4(){
System.out.println("记录程序在运行过程中的各种细节,这里有100行代码");
}
}
接口的应用
public interface InterA {
public abstract void method1();
public abstract void method2();
public abstract void method3();
public abstract void method4();
public abstract void method5();
public abstract void method6();
public abstract void method7();
public abstract void method8();
public abstract void method8();
public abstract void method10();
//在这10个抽象函数中我只想使用第五个
}
public abstract class InterAdapter implements InterA{
//这里加上abstract是为了防止外界创建它的对象
@Override
public void method1() {
}
@Override
public void method2() {
}
@Override
public void method3() {
}
@Override
public void method4() {
}
@Override
public void method5() {
}
@Override
public void method6() {
}
@Override
public void method7() {
}
@Override
public void method8() {
}
@Override
public void method10() {
}
}
public class InterImpl extends InterAdapter{
//我需要用到那个方法就重写那个方法就可以了
@Override
public void method5() {
System.out.println("只要用第五个method");
}
}
什么是内部类:
类的五大成员:属性,方法,构造方法,代码块,内部类
在一个类的里面,再定义一个类
举例:在A类的内部再定义B类,B类就被称为内部类
内部类的分类
成员内部类
静态内部类
局部内部类
匿名内部类
前三种了解即可最后一个重点掌握
public class Test {
public static void main(String[] args) {
//创建对象的方式:
//类名 对象名 = new 类名();
//Student s =new Student();
//内部类对象
//Outer.Inner oi =new Outer().new Inner(); 如果修饰符权限为public
//如果修饰符权限是private
Outer o =new Outer();
//1.Object inner = o.getInstance();
System.out.println(o.getInstance());
}
}
public class Outer {
private class Inner{
}
public Inner getInstance(){
return new Inner();
}
}
???写什么好
public class Test {
public static void main(String[] args) {
Outer.inner oi = new Outer().new inner();
oi.method();
}
}
class Outer { // 外部类
private int a = 30;
// 在成员位置定义一个类
class inner {
private int a = 20;
public void method() {
int a = 10;
System.out.println(???); // 10 答案:a
System.out.println(???); // 20 答案:this.a
System.out.println(???); // 30 答案:Outer.this.a
}
}
}
匿名内部类
匿名内部类本质上就是隐藏了名字的内部类.
public class Test {
public static void main(String[] args) {
//整体我们可以理解为Swim接口的实现类对象
//接口多态
Swim s =new Swim(){
@Override
public void swim(){
System.out.println("重写之后游泳方法");
}
};
//编译看坐边,运行看右边
s.swim();
new Swim(){
@Override
public void swim(){
System.out.println("重写之后游泳方法");
}
}.swim();
}
}
匿名内部类真的没有名字吗?
只是不需要我们自己写而已Java已经写了 外部类类名+$+序号