面向对象_抽象类_抽象方法_接口_内部类
in Java with 0 comment

面向对象_抽象类_抽象方法_接口_内部类

in Java with 0 comment

抽象类和抽象方法

  1. 定义:对继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。类的设计应该保证父类和子类能够共享特征。有时将一个父类设计的非常抽象,以至于他没有具体的实例,这样的类叫做抽象类。
  2. 关键字:abstract
  3. abstract可以修饰:类(抽象类)和方法(抽象方法)

抽象类

抽象方法

举例

abstract class Ani {
	public abstract void height();
}

abstract class Person extends Ani {
	String name;
	int age;

	public Person() {

	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public void eat() {
		System.out.println("人吃饭");
	}

	// 这不是抽象方法
//	public void walk() {
//	}
	// 抽象方法
	public abstract void walk();
}

class Student extends Person {
	public Student(String name, int age) {
		super(name, age);
	}

	public void eat() {
		System.out.println("学生多吃有营养的饭");
	}

	public void walk() {

	}

	@Override
	public void height() {

	}
}

abstract注意点

抽象类的匿名子类

匿名子类的非匿名对象

	public static void method1(Person p) {
		p.height();
		p.walk();
	}


main:
		// 匿名子类的非匿名对象
		Person p = new Person() {

			@Override
			public void walk() {
				System.out.println("匿名子类的非匿名对象walk()");
			}

			@Override
			public void height() {
				System.out.println("匿名子类的非匿名对象height()");
			}

		};
		method1(p);

20200824094229

匿名子类的匿名对象

		// 匿名子类的匿名对象
		method1(new Person() {
			
			@Override
			public void height() {
				System.out.println("匿名子类的匿名对象height()");
			}
			
			@Override
			public void walk() {
				System.out.println("匿名子类的匿名对象walk()");
			}
		});

20200824094239

抽象类应用:模版方法设计模式(TemplateMethod)

public class TeamlateTest {
	public static void main(String[] args) {
		SubTemplate sub = new SubTemplate();
		long codingTime = sub.codingTime();
		System.out.println("代码执行时间:" + codingTime);
	}
}

//模版
abstract class Template {
	// 计算代码的执行时间
	public long codingTime() {
		long start = System.currentTimeMillis();
		code();
		return System.currentTimeMillis() - start;
	}

	public abstract void code();
}

//不确定的部分进行子类的重写
class SubTemplate extends Template {

	@Override
	public void code() {
		// 求质数
		for (int i = 1; i <= 1000000; i++) {
			boolean bool = true;
			for (int j = 2; j < Math.sqrt(i) ; j++) {
				
				if (i % j == 0) {
					bool = false;
					break;
				}
			}
			if (bool) {
				System.out.println("1000以内的质数:" + i);
			}
		}
	}

}

20200824101031

接口(interface)

说明

实现

public class InterFaceTest {
	public static void main(String[] args) {
		Birg b = new Birg();
		b.flyMethod();
		b.stop();
	}
}

interface Flyable {
	// 常量
	public static final int MAX_SPEED = 7900;
	int MIN_SPEED = 1;// 默认省略掉了public static final

	// 抽象方法
	public abstract void flyMethod();

	// 接口不能有构造器,也就说明接口不能被实例化
	// Interfaces cannot have constructors
//	public Flyable() {
//		
//	}
	void stop();// 默认省略了public abstract
}

//如果实现类覆盖了接口中的所有抽象方法,则此类可以实例化
class Birg implements Flyable {

	@Override
	public void flyMethod() {
		System.out.println("用翅膀飞");
	}

	@Override
	public void stop() {
		System.out.println("缓慢落地");
	}

}

//如果实现类没有覆盖接口中的所有抽象方法,则此类不可以被实例化,是一个抽象类
abstract class Birg2 implements Flyable {

	@Override
	public void flyMethod() {

	}

}

//*************************
//接口之间可以多继承
interface AA {
}

interface BB {
}

class CC implements AA, BB {
}

//类可以单继承多实现
class EE {
}

class DD
extend EE implements AA,BB
{
}

接口多态性

public class InterFaceTest2 {
	public static void main(String[] args) {
		Phone phone = new Phone();
		stransData(phone);
	}

	//接口的多态性
	private static void stransData(USB usb) {
		usb.start();
		usb.stop();
	}
}

//USB接口协议规范
interface USB {
	// 速率
	public static final int MAX_SPEED = 200;

	// 启动
	public abstract void start();

	// 停止
	public abstract void stop();
}

//手机连接规范
class Phone implements USB {

	@Override
	public void start() {
		System.out.println("手机连接USB,开始工作");
	}

	@Override
	public void stop() {
		System.out.println("手机连接USB,工作结束,退出");
	}

}

//打印机连接规范
class Printer implements USB {

	@Override
	public void start() {
		System.out.println("打印机连接USB,开始工作");
	}

	@Override
	public void stop() {
		System.out.println("打印机连接USB,工作结束,退出");
	}

}

20200824153350

接口的匿名实现类

创建接口的匿名类的非匿名对象

// 创建接口的匿名类的非匿名对象
		USB mp3 = new USB() {

			@Override
			public void start() {
				System.out.println("MP3连接USB,开始工作");
			}

			@Override
			public void stop() {
				System.out.println("MP3连接USB,工作结束,退出");
			}
		};
		stransData(mp3);
	}

20200824153439

创建接口的匿名类的匿名对象

//创建接口的匿名类的匿名对象
		stransData(new USB() {

			@Override
			public void start() {
				System.out.println("U盘连接USB,开始工作");
			}

			@Override
			public void stop() {
				System.out.println("U盘连接USB,工作结束,退出");
			}
		});

20200824153613

面试题:抽象类和接口有哪些异同?

接口的应用(目前了解即可)

代理模式

public class StarTest {
	public static void main(String[] args) {
		Broker broker = new Broker(new Songer());
		broker.interView();
		broker.signUp();
		broker.song();
	}
}

interface Star {
	// 面谈
	public abstract void interView();

	// 签约
	public abstract void signUp();

	// 唱歌
	public abstract void song();
}

//被代理类:歌手
class Songer implements Star {

	@Override
	public void interView() {

	}

	@Override
	public void signUp() {

	}

	@Override
	public void song() {
		System.out.println("明星:唱歌~~~~");
	}

}

//代理类:经纪人
class Broker implements Star {

	private Star star;

	public Broker(Star star) {
		super();
		this.star = star;
	}

	@Override
	public void interView() {
		System.out.println("经纪人面谈");
	}

	@Override
	public void signUp() {
		// 经纪人签约
		check();
		System.out.println("经纪人签约");
	}

	private void check() {
		System.out.println("经纪人检查合同");
	}

	@Override
	public void song() {
		// 经纪人让歌手唱歌
		star.song();
	}
}

20200824154607

工厂模式

笔试题

排错:笔试1

public class IntreFaceOne extends MB implements MA {
	public static void main(String[] args) {
		new InterFaceOne().pX();
	}

	public void pX() {
		System.out.println(x);
	}
}

interface MA {
	int x = 10;
}

class MB {
	int x = 20;
}

答案是错误

System.out.println(x);//报错The field x is ambiguous,x属性是不确定的

因为MA和MB中的属性名一样
如果调用MA中的x:MA.x
调用MB中的x:super.x

修改成正确的:
		System.out.println(super.x);
		System.out.println(MA.x);

排错:笔试2

public class InterFaceTwo implements VC {

	@Override
	public void play() {
		System.out.println("play执行");
	}

	public static void main(String[] args) {
		face = new InterFaceTwo();
		face.play();
	}

}

interface VA {
	void play();
}

interface VB {
	void play();
}

interface VC extends VA, VB {
	InterFaceTwo face = new InterFaceTwo();
}

答案是错误

interface VC extends VA, VB {
	InterFaceTwo face = new InterFaceTwo();
}
face省略了public static final
所以face是常量
不能再main方法中face = new InterFaceTwo();重新创建The final field VC.face cannot be assigned

接口练习(PPT)

Java8中接口新特性

除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法。

格式

  1. 静态方法:public static void method(){方法体},其中public是可以省略的,省略后还是public属性的方法。
  2. 默认方法:public default void method(){方法体},其中public是可以省略的,省略后还是public属性的方法。
public interface CompareA {
	// 静态方法,public是可以省略的。
	public static void method1() {
		System.out.println("CompareA:method1()");
	}

	//省略后还是public修饰的
	static void method2() {
		System.out.println("CompareA:method2()");
	}

	// 默认方法,public是可以省略的。
	public default void method3() {
		System.out.println("CompareA:method3()");
	}

	//省略后还是public修饰的
	default void method4() {
		System.out.println("CompareA:method4()");
	}
}

静态方法的调用

public class SubClassTest {
	public static void main(String[] args) {
		SubClass c = new SubClass();
		// 知识点1: 	接口中定义的静态方法,只能通过接口来调用
		// The method method1() is undefined for the type SubClass
//		c.method1();
		CompareA.method1();
		CompareA.method2();
	}
}

class SubClass implements CompareA {

}

20200825095318

默认方法的调用

public class SubClassTest {
	public static void main(String[] args) {
		SubClass c = new SubClass();

		//知识点2:实现类对象可以调用接口的默认方法
		//如果实现类重写了接口中的默认方法,则调用的是重写的方法
		
		c.method3();
		c.method4();

	}
}

class SubClass implements CompareA {
	@Override
	public void method4() {
		System.out.println("SubClass:method4()");
	}
}

20200825095520

父类和接口出现同名同参数的方法

public class SuperClass {
	public void method3() {
		System.out.println("SupserClass:method3()");
	}
}

public class SubClassTest {
	public static void main(String[] args) {
		SubClass c = new SubClass();
		//知识点3:如果子类(实现类)继承的父类和实现的接口中声明了
		//同名同参数的默认方法,则会调用父类中的同名同参数的
		//默认方法 --->类优先原则
		c.method3();
		
	}
}

class SubClass extends SuperClass implements CompareA {
	@Override
	public void method4() {
		System.out.println("SubClass:method4()");
	}
}

20200825100120

接口多实现中出现同名同参数的默认方法

public interface CompareB {

	public default void method3() {
		System.out.println("CompareB:method3()");
	}

}

//Duplicate default methods named method3 with the parameters () and () are inherited from the types CompareB and CompareA
class SubClass implements CompareA, CompareB {
	@Override
	public void method4() {
		System.out.println("SubClass:method4()");
	}
}
class SubClass implements CompareA, CompareB {

	@Override
	public void method3() {
	}
}

实现类(子类)中调用父类或接口的(默认)方法

class SubClass extends SuperClass implements CompareA {
	@Override
	public void method4() {
		System.out.println("SubClass:method4()");
	}
	public void my() {
		//调用父类的方法
		super.method3();
		
		//调用CompareA中的默认方法
		CompareA.super.method3();
		CompareA.super.method4();
	}
}

内部类

成员内部类

  1. 作为外部类的成员:
    • 调用外部类的结构
    • 可以被static修饰
    • 可以被4种不同的权限修饰
  2. 作为一个类:
    • 类内可以定义属性、方法、构造器等
    • 可以被final修饰,表示此类不能被继承。言外之意,不使用final,就可以被继承
    • 可以被abstract修饰
public class InnerClassTest {

}

class Person {
	String name;
	int age;

	// 静态成员内部类
	static class Dog {

	}
	
	//可以被4中权限修饰符修饰
	private class A{}
	protected class B{}

	// 非静态成员内部类
	class Brid {
		public String getPersonName() {
			// 调用外部类的结构-方法
			method2();
			// 调用外部类的结构-属性
			return name;
		}

	}

	public void method1() {
		// 方法中定义局部内部类
		class AA {

		}
	}

	public Person() {
		// 构造器中定义局部内部类
		class CC {

		}
	}

	{
		// 代码块中定义局部内部类
		class BB {

		}
	}

	public void method2() {
		System.out.println("method2");
	}
}

局部内部类

class InnerClass {
	public void method1() {
		// 方法中定义局部内部类
		class AA {

		}
	}

	public InnerClass() {
		// 构造器中定义局部内部类
		class CC {

		}
	}

	{
		// 代码块中定义局部内部类
		class BB {

		}
	}
}

内部类关注的问题

如何实例化成员内部类的对象

InnerClassTest代码

		//实例化非静态成员内部类
		Person p = new Person();
		Person.Brid brid = p.new Brid();
		//实例化静态成员内部类
		Person.Dog dog = new Person.Dog();

如何在成员内部类中区分调用外部类的结构

class User{
	int age;
	
	class UserData{
		int age;
		public void setAge(int age) {
			//调用形参
			System.out.println(age);
			//调用内部类属性
			System.out.println(this.age);
			//调用外部类属性
			System.out.println(User.this.age);
		}
	}
}

开发中局部内部类的使用

public class InnerClassTest1 {
	
	
	//开发中很少见
	public void method(){
		//局部内部类
		class AA{
			
		}
	}
	
	
	//返回一个实现了Comparable接口的类的对象
	public Comparable getComparable(){
		
		//创建一个实现了Comparable接口的类:局部内部类
		//方式一:
//		class MyComparable implements Comparable{
//
//			@Override
//			public int compareTo(Object o) {
//				return 0;
//			}
//			
//		}
//		
//		return new MyComparable();
		
		//方式二:
		return new Comparable(){

			@Override
			public int compareTo(Object o) {
				return 0;
			}
			
		};
		
	}
	
}

Day15问题

  1. abstract能修饰哪些结构?修饰后,有什么特点?
    • 类:不能实例化,需要通过子类继承,进行子类的实例化。
    • 方法:没有方法体,需要子类继承覆盖方法;抽象方法所在的类一定是抽象类。
  2. 接口能否继承接口?抽象类能否实现接口?抽象类能否继承非抽象的类?
    • 可以
    • 可以
    • 可以
  3. 声明抽象类,并包含抽象方法。测试类中创建一个继承抽象类的匿名子类的对象。
	abstract class A{
		public abstract void getData();
	}

	public class C{
		public static void main(String[] args){
			//匿名子类的非匿名对象
			A a = new A(){
				public void getData(){

				}
			};
		}
	}
  1. 抽象类和接口有哪些共同点和区别?
    • 共同点:
      • 都不能被实例化。
      • 子类(或实现类)必须重写父类(或接口)的所有抽象方法,如果全部重写,此类可以实例化;如果没有全部重写,此类不可以被实例化(需要在加入关键词abstract
    • 不同点:
      • 接口:
        • 不能有构造器。
        • 实现类通过implements实现
        • 多实现。
      • 抽象类:
        • 有构造器。
        • 子类通过extends继承
        • 单继承。
  2. 如何创建静态成员内部类和非静态内部类的对象?
    • 静态成员内部类:
      • 外部类.内部类 标识符 = new 外部类.内部类();
    • 非静态成员内部类:
      • 外部类 标识符1 = new 外部类();
      • 外部类.内部类 标识符2 = 标识符1.new 内部类();