内容多,第二次复习时写的
一、抽象类
1、本质:
当一个类不能描述一个具体对象时我们把它叫做抽象类
2、与普通类的区别:
它跟普通类一样可以定义成员方法和变量,但是不能实例化,它可以和普通类一样实现多态、向上转型、动态绑定以及拥有构造方法等等
(它的主要作用就是用来继承的)
这里举个实现的例子:
public abstract class Shape1 {
public abstract void draw();
}
public class Cycle1 extends Shape1{
public void draw(){
System.out.println("打印一个圆形");
}
}
public class Rect1 extends Shape1{
public void draw(){
System.out.println("打印一个矩形");
}
}
public class java0712 {
public static void func(Shape1 shape1){ //这里实际上就是向上转型
shape1.draw();
}
public static void main(String[] args) {
func(new Cycle1());
func(new Rect1());
}
}
我们可以注意到,子类如果继承了抽象类,一定要重写抽象类的抽象方法,在重写时子类修饰访问权限要大于等于父类的访问权限否则会报错
还有一个要注意的小例子:
public abstract class Shape1 {
public abstract void draw();
}
abstract class A extends Shape1{
abstract void text();
}
class B extends A{
public void draw(){
}
public void text(){
}
}
这里就是说如果是一个抽象类(A)继承了一个抽象类(Shape),那就不需要重写抽象方法了,但是当另一个不是抽象类的类继承了A,那就不仅要重写A的,而且也要重写Shape的抽象方法
小结:
1、回想之前的dog和cat都继承的animal就可以定义成一个抽象类,因为它没有具体的作用,并且不能准确指定一个对象
2、private、static、final修饰方法时不能被重写
二、接口
1、定义:
任何类型只要实现了接口定义的成员,就可以被当作接口来使用,从而实现多态和代码复用等功能
2、特点:
接口中的成员变量和成员方法前面默认加了这个(如下)
public interface IShape {
// public static final int a = 10;
int a = 10;
// public abstract void draw();
void draw();
}
这样就可以让代码变得简洁了
3、性质:
接口中的方法不能有具体的实现,并且也不能进行实例化
一个类可以通过关键字implement来实现多个接口
public class Cycle2 implements IShape{
public void draw(){
System.out.println("打印一个圆形");
}
public void find(){
System.out.println("寻找一个圆形");
}
}
public class java0713 {
public static void func(IShape iShape){
iShape.draw();
if(iShape instanceof Cycle2){
Cycle2 cycle2 = (Cycle2) iShape;//向下转型,此时就能调用Cycle2中的方法了
cycle2.find();
}
}
public static void main(String[] args) {
func(new Cycle2());
}
}
那接口跟抽象类的区别是什么?
答:接口不能写构造方法,并且成员方法和成员变量类型是默认的

了解完接口得到的拓展:
1、我们可以利用一个类可以实现多个接口(用逗号隔开)的性质来间接的实现"多继承"
2、我们可以通过接口来忘记类型,直接满足接口性质就使用。
4、接口间的多继承
本质就是把多个接口合并成一个接口
interface IRunning {
void run();
}
interface ISwimming {
void swim();
}
// 两栖的动物,青蛙
interface IAmphibious extends IRunning, ISwimming {
}
class Frog implements IAmphibious {
...
}
实现这个接口的类要把他们的方法都重写了
5、两种常见的比较接口
① Comparable接口
public class Student implements Comparable{
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
return this.age - o.age;
} //重写接口中的方法,这里属于是写死了,格式是固定的
}
public class java0716{
public static void main(String[] args) {
Student student1 = new Student("张三",20);
Student student2 = new Student("李四", 19);
int a = student1.compareTo(student2); //student1调用,传入student2
if (a > 0){
System.out.println("student1 > student2");
}
}
}
这里就是通过重写现成的接口方法来实现比较的
② Coparator接口
import java.util.Comparator;
public class Student implements Comparator {
public String name;
public int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compare(Student student1,Student student2) {
return student1.name.compareTo(student2.name);
} //String中正好有compareTo,避免了字符串直接相减报错
}
public class java0716{
public static void main(String[] args) {
Student student1 = new Student("bit",20);
Student student2 = new Student("hello", 19);
int a = student1.compare(student1,student2);
if (a > 0){
System.out.println("student1 > student2");
}else {
System.out.println("student1 <= student2");
}
}
}
这里点开String类型后发现中有compareTo方法
6、内部类
定义:
在java中,可以将一个类定义在另一个类或方法的内部,前者叫做内部类,后者叫做外部类
①静态内部类
class outclass{ //外部类
public int a1 = 1;
private int a2 = 2;
public static int a3 = 3;
public static class innerclass{ //内部类
public int a4 = 4;
private int a5 = 5;
public static int a6 = 6;
outclass y = new outclass();
public void test(){
System.out.println("内部类方法");
}
}
}
public class java0719 {
public static void main(String[] args) {
outclass.innerclass x = new outclass.innerclass();
x.test();
}
}
这里我们发现静态内部类调用自身成员需要实例化内部类对象,这里需要用到外部类 + ‘.’ 的形式
class outclass{ //外部类
public int a1 = 1;
private int a2 = 2;
public static int a3 = 3;
public static class innerclass{ //内部类
public int a4 = 4;
private int a5 = 5;
public static int a6 = 6;
outclass y = new outclass(); //静态内部类中不能直接访问外部非静态成员变量
public void test(){
System.out.println("内部类方法");
System.out.println(y.a1);
System.out.println(y.a2);
System.out.println(a3);
System.out.println(a4);
System.out.println(a5);
System.out.println(a6);
}
}
}
public class java0719 {
public static void main(String[] args) {
outclass.innerclass x = new outclass.innerclass();
x.test();
}
}
通过这几段代码我们又发现,静态内部类中不能直接访问外部非静态成员变量,需要对外部类进行实例化
②实例内部类
实例内部类获取对象时依赖外部类的引用
class outclass{ //外部类
public int a1 = 1;
private int a2 = 2;
public static int a3 = 3;
public class innerclass{ //实例内部类
public int a1 = 8;
public int a4 = 4;
private int a5 = 5;
public static int a6 = 6;
outclass y = new outclass();
public void test(){
System.out.println("内部类方法");
System.out.println(y.a1);
System.out.println(a2);
System.out.println(a3);
System.out.println(a4);
System.out.println(a5);
System.out.println(a6);
}
}
}
public class java0719 {
public static void main(String[] args) {
outclass y = new outclass(); //注意这里!!!
outclass.innerclass x = y.new innerclass();
x.test();
}
}
这里我们能发现,外部内部成员变量同名时,优先内部,调用外部的话需要前面加上外部引用
③局部内部类(不常用,就先带过了)
④匿名内部类(简单认识下)
没有名字且只能用一次
interface Greeting {
void greet();
}
public class Test {
//
类体
}; –¨ ˝ ¿˛
public static void main(String[] args) {
Greeting greeting = new Greeting() {
@Override
public void greet() {
System.out.println("Hello!");
}
};
greeting.greet();
}
}

完