接口、抽象类以及匿名内部类的学习
用IDEA学习Java的第八天
instanceof和类型转换
-
instanceof的作用就是判断左边对象是否是右边类的实例,判断对象是什么类型。
System.out.println(A instanceof B);//判断对象A是否属于类B的类型,A和B必须是父子关系,否则编译报错 -
类型转换
-
父类引用指向子类的对象
-
把子类转换为父类,向上转型:
//Person为student的父类 public class Application{ public static void main(String[] args){ //类型转换:子类转换为父类 //子类转换为父类,可能会丢失一些自己的方法 Student student=new Student(); Person person=student; } } -
把父类转换为子类,向下转型强制转换
//Person为student的父类 //eat()方法为Student类所独有 public class Application{ public static void main(String[] args){ //类型转换:父类转换为子类 Person person=new Student(); Student student=person; student.eat; } }
-
-
代码实例
主方法:
package com.zjl.oop.Demo05; public class Application { public static void main(String[] args) { Person student = new Student(); // Object>String // Object>Person>Teacher // Object>Person>Student // instance判断对象是什么类型 // instanceof判断左边对象是否是右边类的实例 //System.out.println(A instanceof B);A和B必须是父子关系 System.out.println(student instanceof Object);//true System.out.println(student instanceof Person);//true System.out.println(student instanceof Student);//true System.out.println(student instanceof Teacher);//false //System.out.println(student instanceof String);//编译错误 System.out.println("*********************"); Object student1=new Student(); System.out.println(student1 instanceof Object);//true System.out.println(student1 instanceof Person);//true System.out.println(student1 instanceof String);//false System.out.println(student1 instanceof Student);//true System.out.println(student1 instanceof Teacher);//false System.out.println("*********************"); Student student2=new Student(); System.out.println(student2 instanceof Object);//true System.out.println(student2 instanceof Person);//true System.out.println(student2 instanceof Student);//true // System.out.println(student2 instanceof String);//编译错误 // System.out.println(student2 instanceof Teacher);//编译错误 //高 低 高转低需强制类型转换 Person person=new Teacher(); ((Teacher)person).play();//强制类型转换 //低转高 子类转换为父类就会丢失一些方法 Teacher teacher=new Teacher(); Person person1=teacher; person1.run(); } }Person类:
package com.zjl.oop.Demo05; public class Person { public void run(){ System.out.println("奔跑吧!sao年"); } public void eat(){ System.out.println("我爱徐大sao!!!"); } }Student类:
package com.zjl.oop.Demo05; public class Student extends Person{ }Teacher类:
package com.zjl.oop.Demo05; public class Teacher extends Person{ public void play(){ System.out.println("打篮球了"); } }
static关键字
- static关键字的主要用途:通过static修饰的方法或者成员变量不需要对象来进行访问,只要类被加载了,就可以通过类名进行访问。
package com.zjl.oop.Demo06;
public class Student {
//定义一个静态成员变量 多线程可用到
private static int age;
//定义一个非静态成员变量
private int score;
public static void run(){
}
public void go(){}
public static void main(String[] args) {
Student student=new Student();
run();
student.go();
age=30;
System.out.println(age);
student.score=100;
System.out.println(student.score);
}
}
-
static代码块
static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
package com.zjl.oop.Demo06;
public class Person {
{
System.out.println("输出一个匿名代码块");
}
//静态代码块只执行一次
static{
System.out.println("输出第一个静态代码块");
}
static{
System.out.println("输出第二个静态代码块");
}
public Person() {
System.out.println("输出构造方法");
}
public static void main(String[] args) {
Person person=new Person();
System.out.println("*******************");
Person person1=new Person();
}
}
运行结果:
输出第一个静态代码块
输出第二个静态代码块
输出一个匿名代码块
输出构造方法
输出一个匿名代码块
输出构造方法
Abstract抽象类
- abstract修饰符可以用来修饰方法,也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
- 抽象类中可以没有抽象方法,但是由抽象的方法的类一定要声明为抽象类。
- 抽象类不能使用new关键字来创建对象,它是用来让子类继承的。
- 抽象方法,只有方法声明,没有方法实现,它是用来让子类实现的。
- 子类继承抽象类,那么就必须要实现抽象类中没有实现的抽象方法,并且该子类中不能有抽象方法,否则该子类也必须是抽象类,让子子类去实现抽象类的抽象方法。
- 抽象类可以有构造方法,只是不能直接创建抽象类的实例对象而已。在继承了抽象类的子类中通过super()或super(参数列表)调用抽象类中的构造方法。
package com.zjl.oop.Demo07;
//抽象类
public abstract class Action {
//抽象方法,只有方法名字,没有方法的实现
public Action() {
System.out.println("我是抽象类的构造方法");
}
public abstract void doSomething();
//抽象类的特点
//1、不能new这个抽象类,只能靠子类去实现它
//2、抽象类中可以写普通的方法
//3、抽象方法必须在抽象类中
}
package com.zjl.oop.Demo07;
public class A extends Action{
public A() {
super();
}
@Override
//重写抽象方法
public void doSomething() {
}
public static void main(String[] args) {
A a=new A();
}
}
编译结果:
我是抽象类的构造方法
抽象类中的构造方法:
package com.zjl.oop.Demo07;
public abstract class Test {
int a=8;
public Test(){
a=6;
}
public Test(int i){
a=i;
}
public abstract void Test();
}
class B extends Test{
public B(){
super();
}
public B(int a){
super(a);
}
@Override
public void Test() {
}
public static void main(String[] args) {
B b=new B();
B b1=new B(10);
System.out.println(b.a);
System.out.println(b1.a);
}
}
接口
接口就是规范,定义的是一组规则
声明接口的关键字是interface,接口也是一种特殊的类,一个接口中包括永远不变的常量和没有方法体的抽象方法。一个接口就是描述一种能力,接口的作用就是告诉类,你要实现我这种接口代表的功能,你就必须实现某些方法,我才能承认你确实拥有该接口代表的某种能力。
编程就是约束和实现分离:面向接口编程
重点:
-
*我们不能直接去实例化一个接口,因为接口中的方法都是抽象的,是没有方法体的*,这样怎么可能产生具体的实例呢?但是,*我们可以使用接口类型的引用指向一个实现了该接口的对象,并且可以调用这个接口中的方法*。因此,上图中最后的方法调用我们还可以这样写:(实际上就是使用了Java中多态的特性)
USB usb=new UpanServiceImpl(); usb.read(); usb.write(); USB usb1=new JanpanServiceImpl(); usb1.write(); usb1.read(); -
一个类可以实现不止一个接口。
-
一个接口可以继承于另一个接口,或者另一些接口,接口也可以继承,并且可以多继承。
-
一个类如果要实现某个接口的话,那么它必须要实现这个接口中的所有方法。
接口的作用:
1、定义一个约束。
2、定义一些方法,让不同的人去实现这些方法。
3、接口中的默认的方法都是public abstract类型的
4、接口中定义的常量都是public static final类型
5、接口不能被实例化,接口中没有构造方法
6、implements可以实现多个接口
7、在实现接口中方法时,必须要重写接口中的方法。
代码实例:
定义一个UserService接口:
package com.zjl.oop.Demo08;
//定义的关键字是interface
public interface UserService {
//接口中定义的常量是静态的
public static final int age=99;
//接口中的所有定义都是抽象的 public abstrat
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
/*
接口的作用:
1、定义一个约束。
2、定义一些方法,让不同的人去实现这些方法。
3、接口中的默认的方法都是public abstract类型的
4、接口中定义的常量都是public static final类型
5、接口不能被实例化,接口中没有构造方法
6、implements可以实现多个接口
7、在实现接口中方法时,必须要重写接口中的方法。
*/
定义一个实现接口的类:
package com.zjl.oop.Demo08;
//实现接口
//实现了接口的类就需要重写接口中的方法
//利用接口我们可以实现多继承
public class UserServiceImpl implements UserService,TimeService{
String name;
public UserServiceImpl(String name){
this.name=name;
}
@Override
public void add(String name) {
System.out.println("增加了"+name);
}
@Override
public void delete(String name) {
System.out.println("删除了"+name);
}
@Override
public void update(String name) {
System.out.println("更新了"+name);
}
@Override
public void query(String name) {
System.out.println("查到了"+name);
}
@Override
public void time() {
}
}
主方法:
package com.zjl.oop.Demo08;
public class Application {
public static void main(String[] args) {
UserServiceImpl user=new UserServiceImpl("周乐乐");
user.add(user.name);
user.delete("周一");
user.query("周二");
user.update("周三");
}
}
多态补充
一个父类会有很多子类,子类会有很多状态,称之为多态。例如:动物类作为一个父类,狗类和鸡类继承动物类之后,狗类会发出吠叫,而鸡类会发出鸡鸣,子类会产生多种状态,为减少代码,使得代码变得更加简洁,出现了多态。
Animal animal=new Gog(); //向上转型,父类类型的引用指向子类的对象
Animal animal=new Chicken(); //向上转型,父类类型的引用指向子类的对象
匿名内部类
匿名内部类的定义方法
- 操作符:new;
- 一个要实现的接口或要继承的类,案例一中的匿名类实现了HellowWorld接口,案例二中的匿名内部类继承了Animal父类;
- 一对括号,如果是匿名子类,与实例化普通类的语法类似,如果有构造参数,要带上构造参数;如果是实现一个接口,只需要一对空括号即可;
- 一段被"{}"括起来类声明主体;
- 末尾的";"号(因为匿名类的声明是一个表达式,是语句的一部分,因此要以分号结尾)。
实现接口的匿名内部类
package com.oop.demo12;
public class Test {
public static void main(String[] args) {
//没有名字初始化类,不用将实例保存在变量中
new Apple().eat();
//匿名内部类实现UserService接口
UserService userService=new UserService(){
@Override
public void run() {
System.out.println("跑步啦");
}
};
userService.run();
}
}
class Apple{
public void eat(){
System.out.println("我要吃苹果");
}
}
interface UserService{
void run();
}

浙公网安备 33010602011771号