一、制作API
*1)需要定义一个类工具类:ArrayTool数组工具类:给该类写上文档注释(每一个静态方法都需要使用文档注释)
* 2)需要将该类的无参私有化,目的是为了让外界创建对象
* 3)ArrayTool中的成员方法全部用static修饰
* 4)测试完毕
* 5)如何制作API文档
*
* 针对ArrayTool来制作
*
* 打开dos—->javadoc -d 目标名(文件名) -author -version ArrayTool.java
public class ArrayDemo {
public static void main(String[] args) {
//定义一个数组,静态初始化
int[] arr = {24,69,80,57,13} ;
//遍历数组
ArrayTool.printArray(arr) ;
//获取数组中的最大值
int result = ArrayTool.getMax(arr) ;
System.out.println("result:"+result);
//查询577元素
int index = ArrayTool.getIndex(arr, 577) ;
System.out.println("index:"+index);
int index2 = ArrayTool.getIndex(arr, 57) ;
System.out.println("index2:"+index2);
}
}
/**
* 该类是针对数组操作的一个工具类,里面有一些对数组操作的功能
* @author Sunshine
* @version V1.0
* */
public class ArrayTool {
//无参构造私有,目的为了不让外界其对象
private ArrayTool(){
}
/**
* 该方法是针对数组的遍历的方法,遍历的元素[元素1, 元素2, 元素, ....]
* @param arr :需要被遍历的数组
* */
public static void printArray(int[] arr){
System.out.print("[");
for(int x = 0 ; x < arr.length ; x ++){
if(x==arr.length-1){
System.out.println(arr[x]+"]");
}else{
System.out.print(arr[x]+", ");
}
}
}
/**
* 该方法是针对数组获取最大值的方法
* @param arr :需要被遍历的 数组,可以获取每一个元素
* @return 返回的就是数组中最大值
*
* */
public static int getMax(int[] arr){
//定义参照物
int max = arr[0] ;
//遍历其他索引
for(int x = 1 ; x < arr.length ;x ++){
//判断
if(arr[x]>max){
max = arr[x] ;
}
}
return max ;
}
/**
* 该方法是查询数组中的元素在数组中第一次出现的索引
* @param arr : 需要查询的数组
* @param value:需要被查找的远古时
* @return 如果查到了当前索引对应的元素,那么就直接返回当前索引,如果查不到,则返回-1
* */
public static int getIndex(int[] arr,int value){
//假设法
//定义一个索引:假设查不到
int index = -1 ;
//遍历数组
for(int x = 0 ; x < arr.length ; x ++){
//判断:如果刚好查到的x索引对应的元素和value相等,那么返回该索引
if(arr[x]==value){
//表查到了
//给索引遍历重新赋值
index = x ;
break ;
}
}
return index ;
}
}
二、内部类
1、内部类:在一个类中定义另一个类,那么把这种情况
举例:
在类A中定义一个类B,那么类B就是类A的内部类,同理,类A就是类B的外部类
内部类是直接可以访问外部类的成员,包括私有
外部类想要访问内部类的成员,必须通过创建内部类的对象访问该内部类的成员
//外部类
class Outer{
//外部类的成员变量
// public int num = 100 ;
private int num = 20 ;
//内部类
class Inner{
//内部类的成员方法
public void show(){
System.out.println(num);
}
}
//外部类的成员方法
public void method(){
// show() ;
//创建内部类对象
Inner i = new Inner() ;
i.show() ;
}
}
//测试类
public class InnerDemo {
public static void main(String[] args) {
}
}
2、内部类的分类:
* 成员内部类:在外部类的成员位置
* 局部内部类:在外部了的局部位置定义的这个类
//外部类
class Outer2{
//外部类的成员变量
public int num = 100 ;
//成员内部类
/*class Inner2{
}*/
//外部类的成员方法
public void method(){
//局部位置
class Inner2{
}
}
}
//测试类
public class InnerDemo2 {
public static void main(String[] args) {
}
}
3、成员内部类
* 在测试类中需要访问成员内部类中的成员的方法:
*
* 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
//外部类
class Outer3{
//定义外部类的变量
public int num = 10 ;
//成员内部类(非静态成员内部类)
class Inner3{
//内部类的成员方法(非静态的成员方法)
public void show(){
System.out.println(num);
}
}
/*public void method(){
Inner3 i = new Inner3() ;
i.show() ;
}*/
}
//测试类
public class InnerDemo3 {
public static void main(String[] args) {
/**
* 需求:现在需要访问Inner3成员内部类中的show()方法
* */
// Inner3 i = new Inner3() ; //Inner3是一个成员内部类
// 外部类名.内部类名 对象名 = 外部类对象.内部类对象;
Outer3.Inner3 oi = new Outer3().new Inner3() ;
//使用对象名调用show()方法
oi.show() ;
}
}
4、成员内部类的修饰符:
* private :为了保证数的安全性
* static修饰:为了方便调用
* 如果成员内部类被static修饰,那么要访问外部类的成员变量,这个变量必须被static修饰
* 静态的成员内部类访问该类中的成员方法:
* 格式:外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
*
//外部类
class Outer4{
//外部类的两个成员变量
public static int num = 10 ;
public static int num2 = 20 ;
/**
* 结论:
* 对于静态的成员内部类来说,无论静态成员内部类中的成员方法是静态还是非静态的,要访问外部类的成员变量,该变量必须被static修饰
* */
//定义一个静态的成员内部类
public static class Inner4{
//非静态的内部类的成员方法
public void show(){
System.out.println(num);
System.out.println(num2);
}
//静态的内部类的成员方法
public static void show2(){
System.out.println(num);
System.out.println(num2);
}
}
}
//测试类
public class InnerDemo4 {
public static void main(String[] args) {
//需求:要访问静态成员内部类Inner4里面的show(),show2()方法
//外部类名.内部类 对象名 =外部类对象.内部类对象;
// Outer4.Inner4 oi = new Outer4().new Inner4() ;
// oi.show() ;
//静态的成员内部类访问该类中的成员方法:
//格式:外部类名.内部类名 对象名 = new 外部类名.内部类名() ;
Outer4.Inner4 oi = new Outer4.Inner4() ;
oi.show() ;
oi.show2() ;//静态方法
System.out.println("--------------");
//show2()还有另外一种访问方式:
Outer4.Inner4.show2() ;
}
}
5、局部内部类:
* 定义在外部类的局部位置
*
* 结论:
* 无论是局部内部类还是成员内部类(非静态的)都可以直接访问外部类的成员,包括私有
*
* 面试题:
* 局部内部类访问局部变量会出现问题?
* 当前局部变量报错,必须用final修饰;为什么用final修饰?
* 是由于局部变量是随着方法调用而生成的,随着方法的调用完毕消失,而现在局部位置有一个局部内部类它要在自己的成员方法位置访问当前的局部变量
* 必须把变量变成一个常量,(需要用final:自定义常量),这样的一个变量的值永远是固定的!
//外部类
class Outer5{
//外部类的成员变量
// public int num = 100 ;
private int num = 100 ;
//外部类的成员方法
public void method(){
//局部变量
final int num2 = 200 ; //自定义常量(细节问题)
//局部位置
class Inner5{
//局部内部类的成员方法
public void show(){
System.out.println(num);
//局部内部类中访问局部变量
System.out.println(num2); //jdk1.7才会有这个错误!需要自己添加final jdk1.8---->封装好了,所以不会出现错误!
}
}
Inner5 i = new Inner5() ;
i.show() ;
}
}
//测试类
public class InnerDemo5 {
public static void main(String[] args) {
//对于局部内部类访问具该类的成员方法:创建外部类对象 使用外部类对象调用外部类的成员方法
Outer5 o = new Outer5() ;
o.method();
}
}
6、匿名内部类
* 是内部类的简化版格式
* 前提条件:
* 必须存在一个接口或者是一个类(可以是具体类,也可以是一个抽象类)
*
* 书写的格式:
* new 接口名或者类名(){
* 方法重写;
* }
*
*
* 匿名内部类的实质:
* 继承了该类(抽象类)或者是实现了该接口的子类对象!
//定义一个接口
interface Inter{
//抽象功能
public abstract void show() ;
public abstract void show2() ;
}
//外部类
class Outer6{
//成员方法
public void method(){
//当接口中有一个方法的时候
// new Inter(){
//
// @Override
// public void show() {
// System.out.println("show");
// }
//
// }.show() ;
//当接口中有两个方法的时候
/*new Inter(){
@Override
public void show() {
System.out.println("show");
}
@Override
public void show2() {
System.out.println("show2");
}
}.show() ;
new Inter(){
@Override
public void show() {
System.out.println("show");
}
@Override
public void show2() {
System.out.println("show2");
}
}.show2();*/
//使用接口名 对象名 = 匿名内部类的格式: new 接口名(){
//方法重写();
//}
// Inter i2 = new Inter() ;
Inter i = new Inter(){
@Override
public void show() {
System.out.println("show");
}
@Override
public void show2() {
System.out.println("show2");
}
};
//使用对象名调用
i.show();
i.show2() ;
}
}
//测试类
public class InnerDemo6 {
public static void main(String[] args) {
Outer6 o = new Outer6() ;
o.method() ;
}
}
7、面试题:
要求请填空分别输出30,20,10。
外部类和内部类没有继承关系!
class Outer7 {
public int num = 10;
class Inner7 {
public int num = 20;
public void show() {
int num = 30;
System.out.println(num);
System.out.println(this.num);
System.out.println(new Outer7().num);//要访问外部类的成员变量:匿名对象 :new 外部类名().成员变量
//外部类的this限定
System.out.println(Outer7.this.num);
}
}
}
public class InnerClassTest {
public static void main(String[] args) {
Outer7.Inner7 oi = new Outer7().new Inner7();
oi.show();
}
}
8、匿名内部类面试题:
按照要求,补齐代码
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld”
//接口
interface Inter2{
// void show() ;
public abstract void show() ;
}
class Outer8{
//补齐代码
public static Inter2 method(){ //返回值是一个接口
return new Inter2(){
@Override
public void show() {
System.out.println("helloworld");
}
} ;
}
}
//测试类
public class InnerClassTest2 {
public static void main(String[] args) {
Outer8.method().show();
//当前method()能直接被类名调用---->method()方法是一个静态方法 static
//Outer8.method().show()---->Outer8.method()返回的是一个对象,拿对象调用show()方法
//由于接口只有一个show()方法,最终要去重写show()方法
}
}
9、 匿名内部类在开发中的使用
interface Inter3{
public abstract void study() ;
}
class StudentDemo{
public void method(Inter3 i){//形式参数是一个接口
i.study() ;
}
}
//方式1:
class Armay implements Inter3{
public void study(){
System.out.println("好好学习,天天向上...");
}
}
//方式2:
//测试类
public class OuterTest {
public static void main(String[] args) {
//需求:调用StudentDemo中的method()方法
StudentDemo sd = new StudentDemo() ;
Inter3 i = new Armay() ;
i.study() ;
System.out.println("---------------------");
//方式2:匿名内部类
StudentDemo sd2 = new StudentDemo() ;
sd2.method(new Inter3(){
@Override
public void study() {
System.out.println("好好学习,天天向上...");
}
});
}
}
三、形式参数和返回值问题
如果形式参数是引用类型:(重点)
* 基本数据类型:
*具体类类:如果形式参数是一个具体类,那么需要创建该类对象
*抽象类:如果形式参数是抽象类的情况,那么需要自定义一个抽象类的子类,来进行实例化(创建对象)!,创建对象的实质:抽象类多态!
* 接口:如果形式参数是接口情况,那么需要自定义一个接口的子实现类,然后通过接口多态的形式给接口进行实例化!(接口多态!)
返回值的结论:针对引用类型:
* 具体类:直接返回该类对象(通常实际开发中使用的是匿名对象)
* 抽象类:返回值如果是抽象类,需要的返回是该抽象类的子类对象
* 接口:返回值如果是接口类型,需要的是返回该接口的子实现类对象(通过子实现类进行实例化!)
1、基本数据类型
形式参数:
基本数据类型,你要什么数据类型,在实际传参的时候就传什么数据类型;形式参数的改变对实际参数没有影响(String是引用类型和基本数据类型的效果一样String s =”abc”)
class Demo{
//成员方法
public float sum(float a,float b){
return (a + b) ;
}
}
public class StudentTest {
public static void main(String[] args) {
//两个实际参数
/*int a = 10 ;
int b = 20 ;*/
float a = 10.0F;
float b = 12.34F;
//需求:需要调用sum来进行求和
Demo d = new Demo() ;
float result = d.sum(a, b) ;
System.out.println("result:"+result);
}
}
2、如果形式参数是引用类型:
具体类类:如果形式参数是一个具体类,那么需要创建该类对象人
//定义一个类
class Student{
public void show(){
System.out.println("好好学习,天天向上...");
}
}
class StudentDemo{
public void method(Student s){//形式参数是一个引用类型,那么需要该类对象Student s = new Student() ;
s.show() ;
}
}
public class StudentTest {
public static void main(String[] args) {
//需求:需要调用StudentDemo这个类中method()方法
//需要创建StudentDemo这个类的对象
StudentDemo sd = new StudentDemo() ;
//创建Student类的对象
Student s = new Student() ;
sd.method(s) ;//s就代表Student类的对象,把空间地址值作为参数传递
}
}
3、返回值:直接返回该类对象(通常实际开发中使用的是匿名对象)
//定义一个类
class Student{
public void show(){
System.out.println("好好学习,天天向上...");
}
}
class StudentDemo{
public Student method(){
//如果方法的返回值是一个具体的类,那么需要该类对象
//Student s = new Student() ;
//return s ;
return new Student() ;
}
}
//测试类
public class StudentTest {
public static void main(String[] args) {
//返回值是具体的类:
//创建StudentDemo类对象
StudentDemo sd = new StudentDemo() ;
Student s = sd.method() ;
s.show();
}
}
二、抽象类
1、如果形式参数是抽象类的情况,那么需要自定义一个抽象类的子类,来进行实例化(创建对象)!,创建对象的实质:抽象类多态!
//声明一个抽象类
abstract class Person{
public abstract void study() ;
}
//定义一个PersonDemo类
class PersonDemo{
//成员方法
public void method(Person p){//Person p = new Perosn();//错误的:抽象类不能实例化---->抽象类的多态:Person p = new Student2() ;
p.study() ;
}
}
//自定义一个抽象的子类来进行Person的实例化
class Student2 extends Person{
@Override
public void study() {
System.out.println("good good study ,day day up!");
}
}
//测试类
public class PersonTest {
public static void main(String[] args) {
//需求:调用PersonDemo类中method()方法
//创建PersonDemo类的对象
// PersonDemo pd = new PersonDemo() ;
pd.method(p) ;//抽象类不能实例化
// //需要使用抽象类多态来实例化
// Person p = new Student2() ;
// pd.method(p) ;
//链式编程:
new PersonDemo().method(new Student2()) ;
}
}
2、返回值如果是抽象类,需要的返回是该抽象类的子类对象
abstract class Person2{
public abstract void show() ;
}
//定义PersonDemo2类
class PersonDemo2{
// 如果一个方法的返回值是一个抽象类,需要的返回是该抽象类的子类对象
/*Person2 p = new Teacher() ;
return p ;*/
//直接返回匿名对象
return new Teacher() ;//Person2 p = new Teacher() ;
}
}
//抽象类的子类
class Teacher extends Person2{
@Override
public void show() {
System.out.println("老师爱高圆圆,爱生活...");
}
}
//测试类
public class PersonTest2 {
public static void main(String[] args) {
//需求:要调用PersonDemo2这个类中的method()方法
PersonDemo2 pd = new PersonDemo2() ;
Person2 p = pd.method() ;//pd.method();return new Teacher() ----->Person2 p = new Teacher() ;//实质还是多态,间接的向下转型
p.show() ;
System.out.println("----------------");
//链式编程
Person2 p2 = new PersonDemo2().method() ;//链式编程
p2.show() ;
}
}
三、接口
1、如果形式参数是接口情况,那么需要自定义一个接口的子实现类,然后通过接口多态的形式给接口进行实例化!(接口多态!)
//定义一个接口
interface Inter{
public abstract void love() ;
}
//定义一个类
class TeacherDemo{
public void method(Inter i){
//接口不能实例化: 如果一个方法的形式参数是一个接口,那么需要创建该接口的子实现类对象
i.love() ;
}
}
//由于接口不能实例化,需要定义接口的子实现类
class Student3 implements Inter{
@Override
public void love() {
System.out.println("学生爱学习,爱java...");
}
}
//测试类
public class TeacherTest {
public static void main(String[] args) {
//需求:需要调用TeacherDemo类中的method()方法
//创建该类对象
TeacherDemo td = new TeacherDemo() ;
//创建该接口对象:通过接口多态
Inter i = new Student3() ; //接口多态
td.method(i) ;
}
}
通过匿名内部类
//定义一个接口
interface Inter{
public abstract void love() ;
}
//测试类
public class TeacherTest {
public static void main(String[] args) {
Inter i = new Inter() {
//匿名内部类
@Override
public void love() {
System.out.println("学生爱学习,爱java...");
}
};
i.love();
}
}
2、返回值如果是接口类型,需要的是返回该接口的子实现类对象(通过子实现类进行实例化!)
//定义一个接口
interface Love{
public abstract void love();
}
//定义一个类
class TeacherDemo2{ //后面反射机制:--->javac TeacherDemo2.java----> TeacherDemo2.class(ClassLoder:类加载器)
//成员方法
public Love method(){ //如果一个方法的返回值是引用类型:接口类型 需要的是该接口对应的子实现类的对象
//由于返回值是是一个接口类型
// Love l = new Teacher2() ;//接口多态
// return l ;
//返回匿名对象
return new Teacher2() ;
}
}
//定义接口的子实现类
class Teacher2 implements Love{
@Override
public void love() {
System.out.println("老师讲解javaSE......");
}
}
//测试类
public class TeacherTest2 {
public static void main(String[] args){
//需求:需要调用TeacherDemo2中的method()
TeacherDemo2 td = new TeacherDemo2() ;
//使用对象名调用功能
Love l = td.method() ;//Love l = new Teacher2(); 实质就是一个接口多态
l.love() ;
}
}