Java基础(二)

您所在的位置:网站首页 特征构造方法 Java基础(二)

Java基础(二)

2024-03-04 04:57| 来源: 网络整理| 查看: 265

IDEA常用快捷键 快捷键功能Alt+回车导入包,自动修正Ctrl+N查找类Ctrl+Shift+N查找文件Ctrl+Alt+L格式化代码Ctrl+Alt+O优化导入的类和包Alt+Insert生成代码(如get,set方法,构造函数等)Ctrl+E或者Alt+Shift+C最近更改的代码Ctrl+R替换文本Ctrl+F查找文本Ctrl+Shift+Space自动补全代码Ctrl+空格代码提示Ctrl+Alt+Space类名或接口名提示Ctrl+P方法参数提示Ctrl+Shift+Alt+N查找类中的方法或变量Alt+Shift+C对比最近修改的代码Shift+F6重构-重命名Ctrl+Shift先上键Ctrl+X删除行Ctrl+D复制行Ctrl+/ 或 Ctrl+Shift+/注释(// 或者/…/ )Ctrl+J自动代码Ctrl+E最近打开的文件Ctrl+H显示类结构图Ctrl+Q显示注释文档Alt+F1查找代码所在位置Alt+1快速打开或隐藏工程面板Ctrl+Alt+ left/right返回至上次浏览的位置Alt+ left/right切换代码视图Alt+ Up/Down在方法间快速移动定位Ctrl+Shift+Up/Down代码向上/下移动。F2 或Shift+F2高亮错误或警告快速定位 关闭当前项目

在这里插入图片描述

方法定义时注意事项:

1.方法应当定义在类当中,但是不能在方法中再定义方法,不能嵌套 2.方法定义的前后顺序无所谓 3.方法定义之后不会执行,如果希望执行,一定要调用:单独调用、打印调用、赋值调用 4.如果方法有返回值,那么必须写上“return 返回值” 5.return之后的返回值数据,必须和方法的返回值类型对应起来 6.对于一个void没有返回值的方法,不能写return后面的返回值,只能写return自己 7.对于void方法当中最后一行的return可以省略不写。 8.一个方法当中可以有多个return,但是要保证同时只有一个会被执行到,两个return不能连写。

方法的重载Overload

对于功能相似的方法,因为参数列表不同,写不同的方法名太过麻烦了,所以引入方法重载的概念。

多个方法的名称相同,但是参数列表不同。

方法重载与下列因素有关: 1.方法的参数个数不同 2.方法的参数类型不同 3.方法的参数多类型顺序不同

方法重载与下列因素无关: 1.与参数的名称无关 2.与方法的返回值类型无关

Java 的数组

数组的特点: 1.数组是一种引用数据类型 2.数组当中的多个数据,类型必须统一,跟JavaScript不同,JavaScript数组中数据的类型可以不同。 3.数组的长度在程序运行期间不可改变

数组的初始化,在内存当中创建一个数组,并且向其中赋予一些默认值

两种常见的初始化数组方式: 1.动态初始化(指定长度) 2.静态初始化(指定内容)

动态初始化数组格式:

数据类型【】 数组名称 = new 数据类型/数组长度

int[] arr1 = new int[300]; String[] arr2 = new String[5]; 静态初始化数组格式:

数据类型【】 数组名称 = new 数据类型【】{元素1、元素2…}

int[] arr = new int[] {5,15,25}; String[] arr2 = new String[] {"hello","world","java"}; 使用静态初始化时格式还可以省略一下

省略格式:数据类型【】 数组名称 = {元素1、元素2…}

注意事项: 1.静态初始化没有直接指定长度,但是仍然会自动推算得出长度 2.静态初始化标准格式可以拆分成为两个步骤

int[] arr1 = {10,20,30}; int[] arr2; arr2 = new int[] {10,20,30}; 使用初始化建议

如果不确定数组当中的具体内容,用动态初始化;否则,已经确定了具体的内容,用静态初始化。

访问数组元素的格式:

数组名称[索引值]

Java的内存需要划分为5个部分

1.栈(stack):存放的都是方法的局部变量。方法的运行一定要在栈当中运行。 局部变量:方法的参数,或者是方法()内部的变量 作用域:一旦超出作用域,立刻从栈内存当中消失 2.堆(heap):凡是new出来的东西,都在堆当中。堆内存里面的东西都有一个地址值:16进制。 堆内存里面的数据都有默认值。规则: 如果是整数 默认为0 如果是浮点数 默认为0.0 如果是字符 默认为’\u0000’ 如果是布尔 默认为false 如果是引用类型 默认为null 3.方法区(Method Area):存储.class相关信息,包含方法的信息。 4.本地方法栈(Native Method Stack):与操作系统相关。 5.寄存器(pc Register):与CPU相关。

面向对象和面向过程 面向过程

当需要实现一个功能的时候,每一个具体的步骤都要亲力亲为,详细处理每一个细节。

面向对象

当需要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我做事儿。

类和对象 类

类:是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。

现实中,描述一类事物:

属性:就是该事物的状态信息 行为:就是该事物能够做什么

举例:小猫

属性:名字,体重,年龄,颜色 行为:走,跑,叫 定义一个标准类

一个标准的类通常要拥有以下四个组成部分: 1.所有成员变量都要使用private关键字修饰 2.为每一个成员变量编写一对getter/setter方法 3.编写一个无参数的构造方法 4.编写一个全参数的构造方法

这样标准的类也叫做Java Bean

例子: 在这里插入图片描述 编写时写完变量可以直接生成getter和setter代码 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

public class Student { private String name; //姓名 private int age; //年龄 //无参数构造方法 public Student() { } //全参数构造方法 public Student(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } } public class DemoStudent { public static void main(String[] args) { Student stu1 = new Student(); stu1.setName("克苏鲁的呼唤"); stu1.setAge(20); System.out.println("name: " + stu1.getName() + ",age:" + stu1.getAge()); System.out.println("======================="); Student stu2 = new Student( "恩齐都", 21); System.out.println("name: " + stu2.getName() + ",age:" + stu2.getAge()); } }

效果: 在这里插入图片描述

对象

对象:是一类事物的具体体现。对象是类的一个实例,必须局部该类事物的属性和行为

类和对象的关系 类是对一类事物的描述,是抽象的 对象是一类事物的实例,是具体的 类是对象的模板,对象是类的实体 在这里插入图片描述 通常情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用。 1.导包,也就是指出需要使用的类在什么位置。 import 包名称.类名称 import cn.itcast.day1.demo1.Student

对于和当前类属于同一个包的情况,可以省略包语句不写

2.创建,格式: 类名称 对象名 = new 类名称();

Student stu = new Student();

3.使用分两种情况 使用成员变量:对象名.成员变量名 使用成员方法:对象名.成员方法名(参数)

局部变量和成员变量不同

1.定义的位置不一样【重点】 局部变量:在方法的内部 成员变量:在方法的外部,直接写在类当中

2.作用范围不一样【重点】 局部变量:只有方法当中才可以使用,出了方法就不能使用了 成员变量:整个类全都可以通用

3.默认值不一样【重点】 局部变量:没有默认值,如果想要使用,必须手动进行赋值 成员变量:如果没有赋值,会有默认值,规则和数组一样

4.内存的位置不一样 局部变量:位于栈内存 成员变量:位于堆内存

5.生命周期不一样 局部变量:随着方法进栈而诞生,随着方法出栈而消失,存在时间要短一些。 成员变量:随着对象创建而诞生,随着对象被垃圾回收而消失。

当方法的局部变量和类的成员变量重名的时候,根据”就近原则“,优先使用局部变量。 如果需要访问本类当中的成员本来,需要使用格式:this.成员变量名

public class Testday1 { //成员变量 String num = "123"; public void call(){ //局部变量 int n = 10; System.out.println(n); } public static void main(String[] args) { System.out.println(num); call(); } } 面向对象三大特征:封装、继承、多态 封装

1.方法就是一种封装 2.关键字private也是一种封装,一旦使用了private进行修饰,那么本类种仍然可以随意访问。但是超出了本类范围就不能再直接访问了。但可以间接访问。间接访问private成员变量,就是定义一对getter/setter方法,类似于JavaScript中的闭包。 对于getter来说,不能有参数,返回值类型和成员变量对应 对于setter来说,不能有返回值。参数类型和成员变量对应

public class Testday1 { //成员变量 String name; //姓名 private int age; //年龄 public void show(){ System.out.println("My name is " + name + "and age is " + age); } //设置一个成员方法,专门用于向age设置数据 public void setAge(int num) { age = num; } //这个成员方法专门用于获取age的数据 public int getAge() { return age; } }

封装就是将一些细节信息隐藏起来,对于外界不可见

继承

继承是多态的前提,没有继承就没有多态 继承主要解决的问题就是:共性抽取

父类:也可以叫做基类 子类:也可以叫做派生类

在继承的关系中,子类就是一个父类,子类可以被当作父类来看待

定义父类的格式:(一个普通的类定义) 定义子类的格式:

public class 子类名称 extends 父类名称 { } //定义一个员工的子类,讲师 public class extendsDemo extends Employee{ } //定义一个父类 员工 class Employee { public void method(){ System.out.println("方法执行!"); } }

在父子类的继承关系中,如果成员变量重名,则创建子类对象时,访问有两种方式:

直接通过子类对象访问成员变量 间接通过成员方法访问成员变量,该方法属于谁,就优先用谁,没有则向上找。

访问成员变量:

局部变量: 直接写成员变量名 本类的成员本类名: this.成员变量名 父类的成员变量: super.成员变量名

继承关系中,父子类构造方法的访问特点:

子类构造方法当中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造。 可以通过super关键字来子类构造调用父类重载构造 super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super构造。 public class extendsDemo extends Employee{ @Override //如果@Override没有报错,则证明重写正确 public void method(){ int a = super.a; } public extendsDemo(){ //super(); //在调用父类无参构造方法 super(20); System.out.println("子类构造方法"); } } //定义一个父类 class Employee { int a; public void method(){ System.out.println("方法执行!"); } public Employee(){ System.out.println("父类无参构造方法!"); } public Employee(int num) { System.out.println("父类有参构造方法!"); } }

super关键字的用法有三种:

在子类的成员方法中,访问父类的成员变量 在子类的成员方法中,访问父类的成员方法 在本类的构造方法中,访问本类的另一个构造方法 class Zi extends Employee { public Zi(){ this(123); //本类的无参构造调用本类的有参构造 } public Zi(int n){ } public Zi(int a,int b){ } }

super和this的应用

public class FuZiDemo { public static void main(String[] args) { Zidemo zi = new Zidemo(); zi.method(); zi.show(); } } class Fu { int num = 10; public void method(){ System.out.println("父类方法"); } } class Zidemo extends Fu { int num = 20; @Override public void method(){ System.out.println("子类方法"); } public void show(){ int num = 30; System.out.println(num); //30 System.out.println(this.num); //20 System.out.println(super.num); } }

在这里插入图片描述 在这里插入图片描述

Java语言中的继承三个特点

在这里插入图片描述

方法的重写(Override)

概念:在继承关系中,方法的名称一样,参数列表也一样 可以使用@Override检查是否正确重写。

public class extendsDemo extends Employee{ @Override //如果@Override没有报错,则证明重写正确 public void method(){ } } //定义一个父类 员工 class Employee { public void method(){ System.out.println("方法执行!"); } }

注意事项:

必须保证父类子类之间的名称相同,参数列表也相同。 子类方法的返回值必须小于等于父类方法的返回值范围 子类方法的权限必须大于等于父类方法的权限修饰符 public > protected > (default) > private 备注:(default)不是关键字default,而是什么都不写,留空 设计原则

对于已经投入使用的类,尽量不要进行修改,推荐定义一个新的类,来重复利用其中共性内容,并且添加改动新内容。 在这里插入图片描述

发红包练习

在这里插入图片描述

import java.util.ArrayList; import java.util.Random; public class SendHongbao { public static void main(String[] args) { //群主 Manager manager = new Manager("群主",100); //三个群成员 Member one = new Member("成员1",0); Member two = new Member("成员1",0); Member three = new Member("成员1",0); manager.show(); one.show(); two.show(); three.show(); System.out.println("***********************"); //群主发80圆,分三个红包 ArrayList redList = manager.send(80,3); //三个成员收红包 one.receive(redList); two.receive(redList); three.receive(redList); manager.show(); //100 - 80 = 20 one.show(); two.show(); three.show(); } } class User{ private String name; //姓名 private int money; //余额,当前用户拥有的钱数 public User(){ } public User(String name, int money) { this.name = name; this.money = money; } //展示一下当前用户有多少钱 public void show(){ System.out.println("我叫:" + name + ",我有:¥" + money); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } } class Manager extends User{ public Manager(){ } public Manager(String name, int money) { super(name, money); } //发红包方法 public ArrayList send(int totalMoney,int count){ //首先需要一个集合,用来存储若干个红包的金额 ArrayList redList = new ArrayList(); //看一下群主自己有多少钱 int ownMoney = super.getMoney(); //群主当前余额 if(totalMoney > ownMoney){ System.out.println("余额不足"); return redList; //返回空集合 } //扣钱,重新设置余额 super.setMoney(ownMoney - totalMoney); //发红包需要平均拆分为count份 int avg = totalMoney / count; int mod = totalMoney % count; //剩下来的零头 //除不开的零头,放在最后一个红包中,把红包全部放到一个集合中 for (int i = 0; i < count - 1; i++) { redList.add(avg); } //最后一个红包 int last = avg + mod; redList.add(last); return redList; } } class Member extends User{ public Member() { } public Member(String name, int money) { super(name, money); } public void receive(ArrayList list){ //从多个红包当中随便抽取一个给自己,随机获取一个集合中的索引编号 int index = new Random().nextInt(list.size()); //根据索引,从集合中删除,并且得到被删除的红包给自己 int data = list.remove(index); //当前成员本来有多少钱 int money = super.getMoney(); //重新设置成员的钱 super.setMoney(money + data); } }

运行结果: 在这里插入图片描述

多态

访问成员变量的两种方式:

直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找

在多态的代码当中,成员方法的访问规则是:

看new的是谁,就优先用谁,没有则向上找 Fu obj = new Zi(); //多态

在这里插入图片描述

对象的向上转型 格式父类名称 对象名 = new 子类名称();Animal animal = new Cat();含义:右侧创建一个子类对象,把它当作父类来看待创建了一只猫,当作动物看待,没问题

注意事项:向上转型一定是安全的。从小范围转向了大范围,从小范围的猫,向上转换成为了更大范围的动物

对象的向下转型

其实就是一个【还原】的动作

格式子类名称 对象名 = (子类名称)父类对象Cat cat = (Cat)animal;含义:将父类对象,【还原成为本来的子类对象】本来是猫,已经被当作动物了,还原回来成为本来的猫

注意事项:

必须保证对象本来创建的时候就是猫,才能向下转型为猫 如果对象创建的时候本来不是猫,现在非要向下转型成为猫,就会报错。 例子: public class DuoTaiDemo { public static void main(String[] args) { //对象的向上转型,父类引用指向子类对象 AnimalClass animal = new CatClass(); animal.eat(); //猫吃鱼 /*对象一旦向上转型为父类,那么就无法调用子类原本特有的方法 animal.catchMouse(); //错误写法 解决方案:用对象的向下转型[还原] * */ //向下转型,进行还原动作 CatClass cat = (CatClass) animal; cat.catchMouse(); } } abstract class AnimalClass { public abstract void eat(); } class CatClass extends AnimalClass { @Override public void eat() { System.out.println("猫吃鱼"); } //子类特有方法 public void catchMouse(){ System.out.println("猫抓老鼠了!"); } }

在这里插入图片描述

USB接口案例 笔记本电脑在这里插入图片描述 案例分析在这里插入图片描述

在这里插入图片描述 USB接口

public interface USBInterface { public abstract void open(); //打开设备 public abstract void close(); //关闭设备 }

public class UsbDemo { public static void main(String[] args) { //首先创建一个笔记本电脑 Computer computer = new Computer(); computer.powerOn(); //准备一个鼠标 // Mouse mouse = new Mouse(); //首先进行向上转型 USBInterface usbMouse = new Mouse(); //参数是USB类型 computer.useDevice(usbMouse); //创建一个USB键盘 Keyboard keyboard = new Keyboard(); //没有使用多态写法 computer.useDevice(keyboard); computer.powerOff(); } } //鼠标就是一个USB设备 class Mouse implements USBInterface { @Override public void open() { System.out.println("打开鼠标"); } @Override public void close() { System.out.println("关闭鼠标"); } } //键盘是一个USB设备 class Keyboard implements USBInterface { @Override public void open() { System.out.println("打开键盘"); } @Override public void close() { System.out.println("关闭键盘"); } } class Computer{ public void powerOn() { System.out.println("笔记本电脑开机"); } public void powerOff() { System.out.println("笔记本电脑关机"); } //使用USB设备的方法,使用接口作为方法的参数 public void useDevice(USBInterface usb){ usb.open(); //打开设备 usb.close();//关闭设备 } } 运行结果:

在这里插入图片描述

构造方法

构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是在调用构造方法。 格式:

public 类名称(参数类型 参数名称){ 方法体 }

注意事项:

构造方法的名称必须和所在类名称完全一样,就连大小写也要一样 构造方法不用写返回值类型,连void都不写 构造方法不能return一个具体的返回值 如果没有编写任何构造方法,那么编译器会默认赠送一个构造方法,没有参数、方法体什么都不做 一旦编写了一个构造方法,那么编译器不再赠送了。 public class Testday1 { //名称Testday1 相同 public Testday1(){ System.out.println("构造方法执行了"); } } Scanner类

Scanner类的功能:可以实现键盘输入数据到程序当中

引用类型一般使用步骤: 1.导包 import 包路径.类名称 只有java.lang包下的内容不需要导包,其他包都需要import语句 2.创建 类名称 对象名 = new 类名称(); 3.使用 对象名.成员方法名()

例子:

import java.util.Scanner; public class ScannerDemo { public static void main(String[] args) { //System.in代表从键盘输入 Scanner scanner = new Scanner(System.in); //获取键盘输入的int数字 int num = scanner.nextInt(); System.out.println("输入的数字是:"+num); //获取键盘输入字符串 String str = scanner.next(); System.out.println("输入的字符串是:"+str); } }

在这里插入图片描述

Random类

Random类用来生成随机数字

获取一个随机的int数字(范围是int所有范围,有正负两种):int num = r.nextInt() 获取一个随机的int数字(参数代表了范围,左闭右开取键):int num = r.nextInt(3) 实际上代表的含义是:[0,3) 也就是0~2 ArrayList类

数组的长度不可以改变,但是ArrayList集合的长度可以随意改变。 对于ArrayList来说,有一个尖括号代表泛型。 泛型:也就是装在集合当中所有的元素,全部是统一类型的。 注意:

泛型只能是引用类型,不能是基本类型。 对于ArrayList集合来说,直接打印得到的不是地址值,而是内容。如果内容是空,得到的是空的忠括号:[]

例子:

import java.util.ArrayList; public class ArrayListdemo { public static void main(String[] args) { //创建了一个ArrayList集合,集合里面装的全部是string字符串类型的数据 //备注:从JDK1.7开始,右侧的括号内部可以不写内容,但本身还是要写的 ArrayList list = new ArrayList(); System.out.println(list); //[] //向集合当中添加一些数据,需要用到add方法 list.add("天气真好"); list.add("雷雨天"); System.out.println(list); } }

在这里插入图片描述 如果希望向集合ArrayList忠存储基本数据类型,必须使用基本类型对应的“包装类”。

基本类型包装类(引用类型,包装类都位于java.lang包下)byteByteshortShortintIntegerlongLongfloatFloatdoubleDoublecharCharacterbooleanBoolean 对象之间比较

==是进行对象的地址值比较,如果确实需要字符串的内容比较,可以使用两个方法。

public boolean equals(Object obj):参数可以是任何对象,只有参数是一个字符串并且内容相同的才会给true;否则返回false。 备注:任何对象都能用Object进行接收

public class EqualDemo { public static void main(String[] args) { String str1 = "hello"; String str2 = "hello"; char[] charArray = {'h','e','l','l','o'}; String str3 = new String(charArray); System.out.println(str1==str2); //true System.out.println(str1==str3); //false System.out.println(str2==str3); //false System.out.println(str1.equals(str2)); //true System.out.println(str1.equals(str3)); //true System.out.println(str2.equals(str3)); //true } }

在这里插入图片描述

静态static关键字

如果一个成员变量使用了static关键字,那么这个变量不再属于对象自己,而是属于所在的类。多个对象共享同一份数据。

public class StaticDemo { public static void main(String[] args) { Student one = new Student("张三",18); one.room = "101教室"; //one的教室和two的教室因为static关键字所以共通 Student two = new Student("李四",20); System.out.println("姓名:" + one.getName() + ",年龄:" + one.getAge() + ",教室:" + one.room); System.out.println("姓名:" + two.getName() + ",年龄:" + two.getAge() + ",教室:" + two.room); } } class Student { private String name; //姓名 private int age; //年龄 static String room; //所在教室 public Student(){ } public Student(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } public String getName() { return name; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } }

在这里插入图片描述 一旦使用使用static修饰成员方法,那么这就成为了静态方法。 静态方法不属于对象,而是属于类的。

如果没有static关键字,那么必须先创建对象,然后通过对象使用成员方法。 对于静态方法来说,可以通过对象名进行调用,也可以直接通过类名来调用。 对于本类当中的静态方法,可以省略类名称。

注意事项:

静态方法只能直接访问静态变量,成员方法可以直接访问成员变量和静态变量 原因:因为在内存中现有静态内容,后有非静态内容 静态方法当中不能使用this 原因:this代表当前对象,通过谁调用的方法,谁就是当前对象 根据类名称访问静态成员变量的时候,就和对象没有关系了,只和类有关系。 静态代码块

格式:

public class 类名称{ static { //静态代码块内容 } }

特点:当第一次用到本类时,静态代码块执行唯一的一次。 静态的内容总是优先于非静态,所以静态代码块比构造方法先执行。

静态代码块典型用途:用来一次性地对静态成员变量进行赋值。

Arrays类

java.util.Arrays是一个与数组相关的工具类,里面提供了大量的静态方法,用来实现数组常见的操作。 public static String toString(数组):将参数数组变成字符串(按照默认格式:【元素1,元素2…】)

public class ArraysDemo { public static void main(String[] args) { int[] intArray = {10,20,30}; //将int数组按照默认格式变成字符串 String intStr = Arrays.toString(intArray); System.out.println(intStr); System.out.println(intStr instanceof String); } }

在这里插入图片描述

抽象abstract

抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束。

//抽象类:抽象方法所在的类必须是抽象类才行。在class前写上abstract即可 abstract class Animal{ //这是一个抽象方法,代表吃东西,但是具体吃什么不确定 public abstract void eat(); }

如何使用抽象类和抽象方法

不能直接创建new抽象类对象 必须使用一个子类来继承抽象父类 子类必须覆盖重写抽象父类当中的所有抽象方法 覆盖重写:子类去掉抽象方法的abstract关键字,然后补上方法体大括号。 创建子类对象进行使用 public class Animalabstract { public static void main(String[] args) { Cat cat = new Cat(); cat.eat(); } } //抽象类:抽象方法所在的类必须是抽象类才行。在class前写上abstract即可 abstract class Animal{ //这是一个抽象方法,代表吃东西,但是具体吃什么不确定 public abstract void eat(); } class Cat extends Animal{ @Override public void eat(){ System.out.println("猫吃鱼"); } }

在这里插入图片描述

接口

接口就是一种公共的规范标准。只要符合规范标准,就可以大家通用。 接口是一种引用数据类型,最重要的就是抽象方法。

如何定义一个接口的格式:

public interface 接口名称 { // 接口内容 }

接口当中可以包含的内容:

常量 抽象方法 默认方法 静态方法 私有方法

在这里插入图片描述

/*在任何版本的Java中,接口都能定义抽象方法 格式: public abstrace 返回值类型 方法名称(参数列表) 注意事项: 1.接口当中的抽象方法,修饰符必须是两个固定的关键字:public abstract 2.这两个关键字修饰符,可以选择性的省略 3.方法的三要素可以随意定义 * */ public interface MyInterface { //抽象方法 public abstract void method1(); } 接口使用步骤 接口不能直接使用,必须有一个“实现类”来实现接口 格式: public class 实现类名称 implements 接口名称{ ... } 接口的实现类必须覆盖重写接口中的所有抽象方法 实现:去掉abstract关键字,加上方法体大括号 创建实现类的对象,进行使用 例子: public class InterfaceDemo { public static void main(String[] args) { /*错误写法,不能直接new接口对象使用 MyInterface inter = new MyInterface(); * */ //创建实现类的对象使用 MyInterfaceImpl impl = new MyInterfaceImpl(); impl.method1(); impl.method2(); } } //使用alt + enter能够快捷产生覆盖MyInterface接口的重写方法 class MyInterfaceImpl implements MyInterface { @Override public void method1() { System.out.println("方法1"); } @Override public void method2() { System.out.println("方法2"); } }

接口

public interface MyInterface { //抽象方法 public abstract void method1(); public void method2(); }

运行结果: 在这里插入图片描述

接口中定义默认方法

格式:

public default 返回值类型 方法名称(参数列表){ 方法体 }

备注:接口当中的默认方法能够解决接口升级的问题。

public interface MyInterface { //抽象方法 public abstract void method1(); public void method2(); //新添加方法改为默认方法,不需要实现类重写 public default void methods3(){ System.out.println("新添加的默认方法"); } } public class InterfaceDemo { public static void main(String[] args) { /*错误写法,不能直接new接口对象使用 MyInterface inter = new MyInterface(); * */ //创建实现类的对象使用 MyInterfaceImpl impl = new MyInterfaceImpl(); impl.method1(); impl.method2(); //调用默认方法,如果实现类中没有,会向上找接口 impl.methods3(); } }

在这里插入图片描述

接口中的私有方法

我们需要抽取一个公共方法,用来解决两个默认方法之间的重复代码问题。但是这个方法不应该让实现类使用,应该是私有化的。

私有方法只有接口自己能够调用。

普通私有方法,解决多个默认方法之间重复代码问题 格式: private 返回值类型 方法名称(参数列表) { } 静态私有方法,解决多个静态方法之间重复代码问题 格式: private static 返回值类型 方法名称(参数列表) { }

例子:

public interface MyInterface { //新添加方法改为默认方法,不需要实现类重写 public default void methods3(){ System.out.println("新添加的默认方法3"); say(); } public default void methods4(){ System.out.println("新添加的默认方法4"); say(); } //私有方法 private void say(){ System.out.println("aaa"); System.out.println("bbb"); System.out.println("ccc"); } } 接口中的常量

接口当中也可以定义成员变量,但是必须使用public static final三个关键字进行修饰。 从效果上看,这就是接口的【常量】 格式:

public static final 数据类型 常量名称 = "数据值";

一旦使用final关键字,就代表不可改变 接口当中的常量一定要进行明确的赋值

使用接口注意事项 接口是没有静态代码块或者构造方法的 一个类的直接父类是唯一的,但是一个类可以同时实现多个接口。 格式: class MyInterfaceImpl implements MyInterface,MyInterface2,MyInterface3 { } 如果实现类所实现的多个接口当中,存在重复的抽象方法,那么只需要覆盖重写一次即可。 如果实现类没有覆盖重写所有接口当中的所有抽象方法,那么实现类就必须是一个抽象类。 如果实现类锁实现的多个接口当中,存在重复的默认方法,那么实现类一定要对冲突的默认方法进行覆盖。 一个类如果直接父类当中的方法,和接口当中的默认方法产生了冲突,优先用父类当中的方法。

一起学习,一起进步 -.- ,如有错误,可以发评论



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3