目录
一、抽象类
1、抽象方法:
将共性的行为(方法)抽到父类之后。由于每一个子类执行的内容是不一样的,所以,在父类中不能确定具体的方法体。该方法就可以定义为抽象方法
2、抽象类:
如果一个类中存在抽象方法,那么该类就必须声明为抽象类
3、抽象方法的定义格式:
public abstract 返回值类型 方法名 (参数列表);
4、抽象类的定义格式:
public abstract class 类名{ }
5、抽象类和抽象方法的注意事项
1、抽象类不能实例化(抽象不能创建对象)
2、抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
3、抽象类可以有构造方法(创建子类是对象时,给属性赋值)
4、抽象类的子类
(1、重写抽象类中的所有抽象方法
(2、子类本身也是一个抽象类
根据代码,感受一下:
框架:
代码实现:
//父类
abstract class Person {
//属性:
private String name;
private int age;
//空参构造
public Person() {
}
//有参构造
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//getter,setter:
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 eat() {
System.out.println("在吃饭");
}
//在校任务:抽象方法
public abstract void task() ;
}
//子类
class Teacher extends Person {
//构造方法:
public Teacher() {
}
public Teacher(String name, int age) {
super(name, age);
}
//重写父类中的抽象方法:
@Override
public void task() {
System.out.println("任务:传授知识");
}
}
class Student extends Person {
public Student() {
}
public Student(String name, int age) {
super(name, age);
}
@Override
public void task() {
System.out.println("任务:在学习");
}
}
class HouseMaster extends Person {
public HouseMaster() {
}
public HouseMaster(String name, int age) {
super(name, age);
}
@Override
public void task() {
System.out.println("任务:管理宿舍");
}
}
public class Abstract {
public static void main(String[] args) {
//创建对象
Teacher t=new Teacher("小张",28);
System.out.println(t.getName()+": "+t.getAge());
t.Eat();
t.Task();
Student s=new Student("静静",18);
System.out.println(s.getName()+": "+s.getAge());
s.Eat();
s.Task();
HouseMaster h=new HouseMaster("小李",35);
System.out.println(h.getName()+": "+h.getAge());
h.Eat();
h.Task();
}
}
运行:
二、接口
1、接口的定义和使用
- 使用关键字interface来定义:
public interface 接口名 { }
- 接口不能实例化
- 接口和类之间是实现关系,通过implements关键字表示
public class 类名 implements 接口名 { }
- 接口的子类(实现类)
- 重写接口中的所有抽象方法
- 或者实现类本身就是抽象类
- 接口和类的实现关系,可以单实现,也可以多实现。
- public class 类名 implement是接口名1,接口名2{ }
- 实现类还可以在继承一个类的同时实现多个接口
- public class 类名 extends 类名 implements 接口名1 , 接口名2 { }
上代码感受:
//父类
abstract class Animal {
//抽象方法
public abstract void eat();
}
//接口
interface Swim {
public abstract void Swim();
}
//子类
//兔子
class Rabbit extends Animal {
//重写父类中的抽象方法
@Override
public void eat() {
System.out.println("兔子在吃胡萝卜");
}
}
//青蛙
class Frog extends Animal implements Swim {
@Override
public void eat() {
System.out.println("青蛙在吃虫子");
}
@Override
public void Swim() {
System.out.println("青蛙在蛙泳");
}
}
//狗
class Dog extends Animal implements Swim {
@Override
public void eat() {
System.out.println("狗在吃骨头");
}
@Override
public void Swim() {
System.out.println("狗刨");
}
}
public class Interface {
public static void main(String[] args) {
//创建对象
Frog f=new Frog();
f.eat();
f.Swim();
//兔
Rabbit r=new Rabbit();
r.eat();
}
}
2、 接口中成员的特点:
- 成员变量只能是常量,默认修饰符:public static final
- 没有构造方法
- 成员方法,默认修饰符:public abstract
3、接口和类之间的关系
- 类和类 —— 继承关系:只能单继承,不能多继承,但是可以多层继承
- 类和接口 —— 实现关系:可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
- 接口与接口 —— 继承关系:可以是单继承,也可以是多继承
三、内部类
1、什么是内部类
顾名思义就是,类里面再定义一个类
class A {
class B {
}
}
A就是外部类,B就是内部类
2、内部类的访问特点:
- 内部类可以直接访问外部类的成员,包括私有
- 外部类要访问内部类的成员,必须创建对象
3、什么时候使用内部类:
B类表示的东西是A的一部分,且B单独存在没有意义
上代码:
class Car {
String carName;//车名
int carAge;//车龄
String carColor;//车色
public void show (Car this) {
System.out.println(this.carName);
Engine e=new Engine();
System.out.println(e.engineName);
}
//内部类
//引擎
class Engine {
String engineName;//引擎名字
int engineAge;//龄
public void Show() {
System.out.println(engineName);
System.out.println(carName);//私有也可以访问
}
}
}
public class InnerClass {
public static void main(String[] args) {
Car c=new Car();
c.carName="奥迪";
c.carAge=1;
c.carColor="蓝色";
c.show();;
}
}
4、内部类的分类:
(1、成员内部类
- 写在成员位置的,属于外部类的成员
- 成员内部类可以被一些修饰符修饰,如:private,public,static等
- 在成员内部类里面,可以定义静态变量
4.获取成员内部类对象的两种方式:
(1、外部类编写方法,对外提供内部类对象
(2、直接创建:外部类名.内部类名 对象名 = 外部类对象 . 内部类对象
上述的例子就是成员内部类
(2、静态内部类
- 成员内部类的一种特殊情况,成员内部类使用static修饰
- 静态内部类只能访问外部类中的静态成员变量和静态成员方法,如果要访问非静态的,需要创建对象
- 创建静态内部类对象的格式:外部类名.内部类名 对象名=new 外部类名.内部类名();
- 调用非静态方法的格式:先创建对象,用对象调用
- 调用静态方法的格式:外部类名. 内部类名.方法名();
上代码:
//静态内部类
class A {
int a=10;
static int b=20;
static class B {
public void show1() {
A a1=new A();
System.out.println(a1.a);
System.out.println(b);
System.out.println("非静态的方法调用了");
}
public static void show2() {
A a1=new A();
System.out.println(a1.a);
System.out.println(b);
System.out.println("静态的方法调用了");
}
}
}
public class InnerClass {
public static void main(String[] args) {
//创建对象
A.B c1=new A.B();
c1.show1();
//静态方法
A.B.show2();
}
}
输出:
(3、局部内部类
- 将内部类定义在方法里面就叫做局部内部类,类似于方法里面的局部内部类,类似于方法里面的局部变量
- 外界是无法直接使用,需要在方法内部创建对象并使用
- 该类可以直接访问外部类的成员,也可以访问方法内的局部变量
上代码:
//局部内部类
class C {
public void show() {
final int a=10;
//局部内部类
class D {//局部内部类
String a2;
int a3;
public void meth1() {
System.out.println("局部内部类的meth1方法");
}
}
//创建局部内部类的对象
D d=new D();
System.out.println(d.a2);
System.out.println(d.a3);
d.meth1();
}
}
public class InnerClass {
public static void main(String[] args) {
C e=new C();
e.show();
}
}
(4、匿名内部类
1、匿名内部类本质上就是隐藏了名字的内部类
2、格式:
new 类名或者接口名() {
重写方法;
};
3、格式的细节
(1、包含了继承或实现,方法重写,创建对象
(2、整体就是一个类的子类对象或者接口的实现类对象
4、使用场景
(1、当方法的参数是接口或者类时
(2、以接口为例,可以传递这个接口的实现类对象
(3、如果实现类只要使用一次,就可以用匿名内部类简化代码
上代码:
//匿名内部类
interface Swim {
public abstract void Swim();
}
public class InnerClass {
public static void main(String[] args) {
//编写匿名内部类
new Swim() {
@Override
public void Swim() {
System.out.println("重写了方法");
}
};
}
}
本期结束啦!下期再见!!!