Java基础之抽象类和接口

Java基础

抽象类

  1. abstract
    1.1 抽象方法
    由abstract修饰的方法,没有方法体
    1.2 抽象类
    由abstract修饰的类,不能创建对象
    抽象类中可以没有抽象方法
    抽象方法所在的类一定是抽象类
    抽象类要有子类创建对象
    子类要创建对象的话,必须实现父类的所有抽象方法,否则该类仍时抽象类,不能创建对象

接口

  1. interface
    一种类别的所有对象都具有的行为放在类里面,不同类别的对象具有的相同行为放接口中。
    1.1 定义接口
    interface 接口名{
    变量:int x = 10; ---------默认 public static final修饰
    方法:jdk1.8之前都是抽象方法(之后可以有普通方法),可以省略abstract,默认修饰符public
    }
	public interface Demo1 {
		int x = 1;
		//有public abstract修饰
		void f();
	}
	
	public class Test2 {

	public static void main(String[] args) {
		//有final修饰
		//Demo1.x = 4;
		//有public static修饰
		System.out.println(Demo1.x);
	}

}

1.2 实现接口
implements
实现接口的类要实现接口中的所有方法,才可以创建对象
如果不实现接口中的所有方法,该类为抽象方法,不可以创建对象

	public class Demo1Impl implements Demo1{
		
		@Override
		public void f() {
			System.out.println("接口实现");
		}
	
	}

1.3 注意
接口和接口之间可以是 继承 关系
类和接口之间可以是 实现 关系,可以实现多个接口
在接口中用default或者static修饰的方法被作为普通方法

	public interface Demo {
		default void test1() {
			System.out.println("test1");
		}
		
		static void test2() {
			System.out.println("test2");
		}
	}
	
	public class DemoImpl implements Demo{

	}
	
	public class Test {

		public static void main(String[] args) {
			Demo.test2();
			DemoImpl di = new DemoImpl();
			di.test1();
		}

	}

实现类的接口和父类都有同名方法,实现类调用的是父类中的方法

	public class SubClass {
		public void test1() {
			System.out.println("subclass");
		}
	}
	
	public class SubDemo extends SubClass implements Demo{

	}

	public class Test {
	
		public static void main(String[] args) {
			//Demo.test2();
			//DemoImpl di = new DemoImpl();
			//di.test1();
			
			SubDemo sd = new SubDemo();
			sd.test1();
		}
		
	}

如果一个类实现了两个接口,这两个接口中有同名的普通方法,会出现编译时错误,必须重写这个同名方法

	public interface Demo {
		default void test1() {
			System.out.println("Demo");
		}
	}
	
	public interface Demo2 {
		default void test1() {
			System.out.println("Demo2");
		}
	}
	
	public class SubDemo2 implements Demo, Demo2{
		//必须重写,否则编译错误
		@Override
		public void test1() {
			//因为test1方法是实例方法,所以用对象调用
			//Demo说明调用的是Demo中的test1方法
			Demo.super.test1();
		}
	
	}

  1. 接口和抽象类的区别
抽象类接口
模板类不同类型的共同行为
不能多继承可以多继承
有构造方法没有构造方法
变量是普通的变量都是公有静态常量
普通方法普通方法由default或static修饰
抽象方法没有默认修饰符抽象方法默认修饰符为public

3.函数式接口
接口中只有一个抽象方法->lambda表达式。
@FunctionalInterface

扩展知识

  1. 内部类
    1.1 类体内部类
	public class Demo {
		//该内部类可以由private static修饰
		//该内部类可以访问外部类的成员
		 class Inner{
			//static int b = 0;//不可以定义静态成员
			final static int c = 0;//可以定义静态常量
			int a;
			void test() {
				System.out.println("类体内部类");
			}
		}
		 
		public static void main(String[] args) {
			//创建内部类对象---Demo.Inner inner = new Demo().new Inner();
			Demo.Inner inner = new Demo().new Inner();
			inner.test();
		}
		
	}
	public class Demo2 {
		public int x;
		public static int y;
		static class Inner{
			int a;
			static int b = 1;//静态内部类可以定义静态和非静态成员
			void test() {
				//x = 2;//静态内部类不能访问外部非静态成员
				y = 3;
				System.out.println("静态内部类");
			}
		}
		public static void main(String[] args) {
			//创建静态内部类对象---Demo2.Inner inner = new Demo2.Inner();
			Demo2.Inner inner = new Demo2.Inner();
			inner.test();
		}
	}

1.2 方法内的内部类

	public class Demo3 {
		int x = 1;
		static int y = 2;
		void test() {
			int a = 3;
			a = 4;
			class Inner{
				int b = 4;//jdk1.7之后默认常量
				//static int c = 5;//不能定义静态成员
				final static int d = 6;//可以定义静态常量
				void f() {
					//a = 8;//如果用到方法中定义的变量,那该变量就变成常量
					//可以访问外部成员
					x = 11;
					y = 22;
					System.out.println("方法内的内部类");
				}
			}
			new Inner().f();
		}
		public static void main(String[] args) {
			new Demo3().test();
		}
	}

1.3 匿名内部类

	public class Demo4 {
		//创建了Object类的子类
		Object obj = new Object() {
			//不是类体不可以有方法,所以这是个类
			public void f() {
				System.out.println("匿名内部类");
			}
			public String toString() {
				return "Hello";
			}
		};
		//创建了IDemo接口的实现类
		IDemo demo = new IDemo() {
	
			@Override
			public void f() {
				System.out.println("接口方法的实现");
			}
			
		};
		
		public static void main(String[] args) {
			//new Demo4().obj.f();//Object里没有f方法,所以编译错误
			System.out.println(new Demo4().obj.toString());//Object里有toString方法,obj重写了该方法
			
			new Demo4().demo.f();
		}
	}
  1. lambda表达式
    2.1函数式接口编程:接口中只有一个抽象方法,把方法通过匿名类实现的方法简化一个表达式的写法------使用lambda表达式
    2.2 写法:()->{}
    ()表示形参列表
    ->符号 goes to
    {}表示方法体
	package com.java.day8;
	/**
	 * lambda表达式
	 * @author ThinPad
	 *
	 */
	interface IA{
		//输出hello
		void test();
	}
	
	public class Demo {
		public static void main(String[] args) {
			/*
			 * IA ia = new IA() {
			 *   @Override 
			 *   public void test() { 
			 * 		System.out.println("hello"); 
			 *   }
			 * }; 
			 * 
			 * ia.test();
			 */
			
			//lambda表达式是上面匿名内部类的一种简写
			IA ia2 = () -> {
				System.out.println("lambda表达式");
			};
			
			ia2.test();
		}
	}

如果方法体中有一条语句,则大括号可省。
参数列表的数据类型可省。
当参数列表中只有一个参数时,则小括号可省。
如果方法体中有一条返回语句,则return可省。
简写方式:方法的归属名::方法名;
简写方式的使用:有与接口中相同返回类型,参数列表相同的方法时使用。

	package com.java.day8;
	
	interface A{
		int test(int x, int y);
	}
	
	public class Demo6 {
	
		public static void main(String[] args) {
			
			Demo6 demo = new Demo6();
			//A a = (x, y) -> {
			//	 return demo.test2(x, y);
			//};
			//System.out.println(a.test(1, 2));
			
			A a = demo :: test2;
			
			System.out.println(a.test(1, 2));
		}
		
		int test2(int x, int y) {
			return x + y;
		}
	}

	package com.java.day8;
	
	interface IDemo{
		void showMessage(String msg);
	}
	
	interface IDemo2{
		int max11(int x, int y);
	}
	
	public class Demo8 {
	
		public static void main(String[] args) {
			IDemo i = System.out::println;
			IDemo2 i2 = Math::max;
			i.showMessage("hello");
			System.out.println(i2.max11(1, 2));
		}
	
	}

	package com.java.day8;
	
	public class Student {
		private String name;
		private int age;
		public Student() {
			System.out.println("no param!");
		}
		public Student(String name, int age) {
			this.name = name;
			this.age = age;
			System.out.println("have param!");
		}
	}
	
	package com.java.day8;

	interface Demo11{
		void getStudent();
	}
	
	interface Demo12{
		void getStudent(String name, int age);
	}
	
	public class Test {
	
		public static void main(String[] args) {
			Demo11 demo = Student::new;
			Demo12 demo2 = Student::new;
			demo.getStudent();
			demo2.getStudent("周", 18);
		}
	
	}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值