1.如果一个类中,有抽象方法的话,那么这个类必须定义为抽象类 抽象类格式: abstract class类名{} 抽象方法格式: 权限修饰符 abstruct 返回值类型 方法名(参数列表); 2.抽象类的本质:强制子类重写抽象方法 3.抽象类的特点: 1.抽象类不能实例化,但是抽象类一定存在最具体的子类,否则没有意义 2.抽象类中可以没有抽象方法(抽象类中没有抽象方法的意义:不能实例化) 4.抽象类的实例化 通过抽象类多态,父类引用指向子类对象,有最具体的子类 5.抽象类的成员特点: (1)成员变量:可以是变量,也可以是自定义常量 (2)成员方法:既可以是抽象方法(必须有abstract),也可以是非抽象方法 (3)构造方法:存在继承关系,子类继承父类,分层初始化 6.abstract不能与那些关键字一起使用: (1)private:被private修饰的方法只能在当前类访问,而abstract需要子类重写 (2)final:final关键字修饰的方法不能被重写 (3)static:与类相关,随着类的加载而加载,而抽象方法需要被子类重写,最终需要使用对象来抽象化多态:Fu fu = new Zi();和static一起使用在父类中没有方法体,加载没有意义2. 接口
1.接口是一种规范,就是能实现接口中的额外功能 接口比抽象类还抽象的一种类型 2.格式: interface 接口名(大驼峰命名法){} class 子实例类名 implements 接口1,接口2...{} 接口名 对象名 = new 子实例类名(); 3.接口中的方法只能是抽象方法,不能有方法体 特点:不能实例化,通过接口多态,所以具有具体的子类 4.接口中的成员特点: (1)成员变量只能是常量,存在默认修饰符: public static final(可以省略不写) (2)接口中的构造方法:没有构造方法 (3)接口中的成员方法:只能是抽象方法,存在默认修饰符:public abstract(可以省略不写) // 默认方法,必须有方法体,接口自己的默认方法 default void 方法名(){ System.out.println("method Inter..."); } //静态方法 public static void 方法名(){ System.out.println("function Inter..."); } 5.关系的区别 (1)类与类的关系:继承关系 (2)类与接口关系:实现关系 一个类继承自另一个类的时候,可以实现多个接口 (3)接口与接口的关系:可以单继承,多继承,多层继承3.形式参数问题
方法的形式参数:基本数据类型/引用数据类型 1.形参为基本数据类型,实际参数就是当前的数据值就行,而且形参的改变不会影响实际参数 2.形参为引用数据类型(空间地址值的传递) (1)具体类:实际参数应该创建当前具体类对象 class Student{ public void study(){ sout("学习Java"); } } class StudentDemo{ public void method(Student student){ student.study(); } } class 测试类{ main(){ StudentDemo student = new StudentDemo(); Student a = new Student(); student.method(a); sout("========================"); student.method(new Student()); sout("========================"); new StudentDemo.method(new Student()); } } (2)抽象类:实际参数传递时创建当前抽象类的子类对象(抽象类多态) abstract class Student{ public abstract void study(); } } class Students extends Student{ public void study(){ sout("学习java"); } } class StudentDemo{ public void method(Student student){ student.study(); } } class 测试类{ main(){ StudentDemo student = new StudentDemo(); Student a = new Students(); student.method(a); sout("========================"); student.method(new Students()); sout("========================"); new StudentDemo.method(new Students()); } } (3)接口:传递接口实现类的对象 interface Student{ public abstract void study(); } class Students implements Student{ public void study(){ sout("学习java"); } } class StudentDemo{ public void method(Student student){ student.study(); } } class 测试类{ main(){ StudentDemo student = new StudentDemo(); Student a = new Students(); student.method(a); sout("========================"); student.method(new Students()); sout("========================"); new StudentDemo.method(new Students()); } } (4)数组:实际参数传递数组对象 import java.util.Arrays; class Array{ public void array(int[] arr){ sout(Arrays.toString(arr)); } } class ArrayTest{ main{ Array a = new Array(); int[] arr1 = new int[4]; a.array(arr1); } }4. 返回值类型问题
返回值类型:基本数据类型/引用数据类型 1.返回值为基本数据类型,直接返回基本数据类型的返回值即可 2.返回值类型为引用数据类型 (1)具体类:需要返回当前类的具体对象 class Student{ public void study(){ sout("学习java"); } } class StudentDemo{ public Student method(){ return new Student(); } } class 测试类{ main(){ StudentDemo a = new StudentDemo(); Student b = a.method(); b.study(); sout("============================="); new StudentDemo.method().study(); } } (2)抽象类:返回当前抽象类的子类对象 abstract class Student{ public abstract void study(); } class Students extends Student{ public void study(){ sout("学习java"); } } class StudentDemo{ public Student method(){ return new Students(); } } class 测试类{ main(){ StudentDemo a = new StudentDemo(); Student b = a.method(); b.study(); sout("============================="); StudentDemo a = new StudentDemo(); a.method().study(); sout("============================="); new StudentDemo.method().study(); } } (3)接口:需要返回子实现类的对象 interface Student{ public abstract void study(); } class Students implements Student{ public void study(){ sout("学习java"); } } class StudentDemo{ public Student method(){ return new Students(); } } class 测试类{ main(){ StudentDemo a = new StudentDemo(); Student b = a.method(); b.study(); sout("============================="); StudentDemo a = new StudentDemo(); a.method().study(); sout("============================="); new StudentDemo.method().study(); } }5.内部类
1.内部类: (1)成员内部类:在外部类的成员位置定义的类 (2)局部内部类:在外部类的成员方法中定义的类 (3)静态内部类 2.访问成员问题 (1)成员内部类:(前提:当前的成员内部类是非静态的) (可以用private修饰,保证数据安全) 可以访问外部类的所有成员,外部类也可以访问内部类的变量和方法 创建内部类对象的方法格式: 外部类名.内部类名 对象名 = new 外部类名().new内部类名(); class Outer{ private String name = "张三"; int age = 14; //内部类 class Inner{ int n = 10; public void show(){ sout(name+age+n); } } //外部类成员方法 public void method(){ Inner inner = new Inner(); inner.show(); } } class 测试类{ main(){ Outer outer = new Outer(); outer.method(); } } (2)局部内部类:局部内部类可以访问外部类所有成员,但是局部内部类的成员只能在创建该局部类的方法中调用 面试题:局部内部类访问局部变量的时候,能访问码?局部变量有什么要求? jdk7或者jdk7以前,局部变量必须显示加入final修饰,否则访问报错 而jdk8已经jvm优化了,此时这个num2就是常量!---使用反编译工具查看内部类的结构--->发现其实已经加入了final 局部变量的生命周期是随着的方法的调用而存在,随着方法的调用结束而消失; 而当前这个方法结束之后,num2局部变量也应该就不存在了,但是我们还在使用内部类对象访问它里面这个成员方法,而对象不会立即被GC立即回收,等待空闲的时候回收没有更多引用的对象,所以此时这些变量应该都是常驻内存,使用final定义----->常量! class Outer4{ private int num = 100 ;//外部类的成员变量 //成员方法 public void method(){ //局部内部类 class Inner4{ //成员方法 public void show(){ //局部变量 int num2 = 20 ; //局部内部类访问局部变量--->能访问吗? // --->此时这个变量有什么要求吗?--有 System.out.println(num2) ;// 没有报错! System.out.println(num) ;//访问外部类的成员 } } //在method方法中,访问show //创建局部内部类对象.show() Inner4 inner4 = new Inner4() ; inner4.show() ; } } //测试类 public class InnerClassDemo4 { public static void main(String[] args) { //创建外部类对象 Outer4 outer4 = new Outer4() ; outer4.method() ; } } (3)静态内部类:用static修饰的成员内部类 静态内部类只能访问外部类的静态成员,外部类访问静态内部类时,可以跳过外部类直接通过内部类访问静态内部类成员 创建静态内部类对象的格式: 外部类名.静态内部类名 变量名 = new 外部类名.静态内部类名();5.权限修饰符和包
1. 同类中 相同包不同类 不同包的子类 不同包的无关类 private √ default √ √ protected √ √ √ piblic √ √ √ √ 2.static在工具类中将构造方法私有化,里面方法加入static,类名访问 3.包-----就是文件夹 真实的开发环境中包需要针对代码分层 代码分包: (1)实体类--存储实体类(描述现实世界事物的) com.qf.pojo/entity/domain //属性私有化,对外提供get/set方法 (2)service层--业务接口层 com.qf.service 举例:UserService //用户注册功能 boolean register(User user) ; boolean login(User user) ; com.qf.service.impl--业务接口的实现 UserServiceImpl实现上面的这些功能 数据从数据库中访问 在业务实现层中调用数据库访问层中的接口方法 (3)持久层(数据库访问层) com.qf.dao UserDao接口 数据访问的接口层//查询数据库中是否有User信息 boolean sleectUser(User user) com.dao.impl UserDaoImpl实现层 数据访问接口实现层 boolean sleectUser(User user) {} (4)控制层 controller层 com.qf.controller 类名:UserController 代码--->调用业务层数据方法 就有业务数据--->利用前后端的交互技术 进行数据的视图的渲染! 4.带包的编译运行 (1)手动方式: 创建com文件夹 子文件夹qf 使用javac对源文件编译 将字节码文件放在qf子文件夹下 带包名运行 java 包名.字节码文件前缀 (2)自动方式 javac -d . java文件-->自动产生文件夹和字节码文件 带包运行即可6 匿名内部类
1.没有名字的类 2.使用场景:很少有为具体类的匿名内部类,因为具体类本身就可以new对象 一般都是抽象类和接口中使用最多 3.格式: //(一般是抽象类名或者接口类名) new 类名(){ 重写抽象类或者接口的抽象方法{ } };------------->不能忘记分号 4.本质:就是继承了该抽象类或者实现了接口的子类对象6.1实 *** 代码
1.有以下代码可看出 (1)使用常规方法我们需要写一个接口实现类,重写接口方法之后去调用方法 (2)使用匿名内部类不需要写接口实现类,直接采用匿名方式去调用方法 interface Inter{ void show(); void show2(); } //定义一个外部类 class Outer{ public void method(){ //1.常规用法 class InterImpl implements Inter{ //访问方式为在方法体后.方法名 public void show(){ System.out.println("这是一个接口实现类"); } public void show2(){ System.out.println("这是一个接口实现类"); } } class Demo{ public void show3(Inter j){ j.show(); j.show2(); } } Demo demo = new Demo(); Inter inter = new InterImpl(); demo.show3(inter); //2.采用匿名内部类 //访问方式为在方法体后.方法名 new Inter(){ public void show(){ System.out.println("这是一个匿名内部类"); } public void show2(){ System.out.println("这是一个匿名内部类"); } }.show(); new Inter(){ public void show(){ System.out.println("这是一个匿名内部类"); } public void show2(){ System.out.println("这是一个匿名内部类"); } }.show2(); //以上访问方式代码量过大,创建一个接口对象来接收 Inter i = new Inter(){ public void show(){ System.out.println("这是一个匿名内部类"); } public void show2(){ System.out.println("这是一个匿名内部类"); } }; i.show(); i.show2(); } } //测试类 public class InnerClassTest{ public static void main(String[] args) { Outer outer = new Outer(); outer.method(); } } 输出结果: 这是一个接口实现类 这是一个接口实现类 这是一个匿名内部类 这是一个匿名内部类 这是一个匿名内部类 这是一个匿名内部类6.2 当方法的形式参数为接口类(抽象类相同)
1.方法的形式参数如果是一个接口类型,调用方法的时候,需要传递接口的子实现类对象 interface Inter{ void show(); void show2(); } //定义一个类,实现接口的方法 class InterDemo{ public void method(Inter inter){ inter.show(); inter.show2(); } } //测试类 public class InnerClassTest{ public static void main(String[] args) { //创建方法对象 InterDemo demo = new InterDemo(); demo.method(new Inter(){ @Override public void show() { System.out.println("这是形式参数为接口类的方法"); } @Override public void show2() { System.out.println("这是形式参数为接口类的方法"); } }); } } 输出结果: 这是形式参数为接口类的方法 这是形式参数为接口类的方法6.3方法返回值为接口(抽象类相同)
1.方法的返回值如果是一个接口,需要接口的子实现类对象 interface Inter{ void show(); void show2(); } //定义一个类,实现接口的方法 class InterDemo { public Inter method() { return new Inter() { @Override public void show() { System.out.println("这是返回值为接口的匿名对象"); } @Override public void show2() { System.out.println("这是返回值为接口的匿名对象"); } }; } } //测试类 public class InnerClassTest{ public static void main(String[] args) { //创建方法对象 InterDemo demo = new InterDemo(); demo.method().show(); demo.method().show2(); System.out.println("========================"); Inter inter = demo.method(); inter.show(); inter.show2(); } } 输出结果: 这是返回值为接口的匿名对象 这是返回值为接口的匿名对象 ======================== 这是返回值为接口的匿名对象 这是返回值为接口的匿名对象6.4 拉姆达表达式
1.JDK8之后,当接口中只有一个抽象方法的时候,那么这个接口可以称为"函数式接口" interface Love{ void love() ; } class LoveDemo{ public void show(Love l){//方法的形式参数是一个接口--->需要接口的子实现类对象 l.love(); } } //测试类 public class InnerClassTest2 { public static void main(String[] args) { //访问的是LoveDemo中的show方法 LoveDemo ld = new LoveDemo() ; //当接口中有且仅有一个抽象方法的时候,那么这个接口可以称为"函数式接口" //函数式接口---->实现方法的时候---->有一个 -> 箭头直接可以实现接口的方法 ld.show( //接口的匿名内部类很多 () ->{ System.out.println("爱生活,爱Java,爱高圆圆"); } ) ; } }6.5匿名类面试题
* 看程序,补全代码--->控制台输出"hello world" * 考点匿名内部类的使用 interface Inter{ void show() ; } class Outer{ //以下为补全代码 public static Inter method(){ return new Inter(){ public void show(){ sout("hello world"); } }; } } public class Test {//测试类 public static void main(String[] args) { Outer.method().show(); //分析思路-->Outer能够直接访问method,说明method是一个静态方法-->能够直接访问show方法,说明是有返回值 } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)