第四周学习总结

day10


01_private关键字


封装手机类测试


/*

按照刚才写法,完成手机类测试

手机类:

品牌brand,价格price,颜色color--->属性加入私有修饰!

打电话callPhone(),发短信sendMsg()

在PhoneTest中进行 手机类的测试,给属性赋值,并且调用成员方法,打印信息!

*/

//定义一个手机类

classPhone{

//属性私有化

privateStringbrand ; //品牌

privateintprice ; //价格

privateStringcolor ; //颜色

//对外提供公共setXXX(赋值的参数)/getXXX()

//给品牌赋值

publicvoidsetBrand(Stringb){ //"华为p40"

brand=b;

}

//获取品牌的值

publicStringgetBrand(){

returnbrand ;

}

//给价格赋值

publicvoidsetPrice(intp){//6799

price=p ;

}

//获取价格的值

publicintgetPrice(){

returnprice ;

}

//给颜色赋值

publicvoidsetColor(Stringc){ //"天空灰"

color=c ;

}

//获取颜色的值

publicStringgetColor(){

returncolor ;

}

//其他成员方法

publicvoidcallPhone(){

System.out.println(brand+"可以打电话了") ;

}

publicvoidsendMsg(StringtoName){

System.out.println("给"+toName+"可以发短信了") ;

}

}

//手机类的测试类

classPhoneTest{

publicstaticvoidmain(String[] args){

//创建手机类对象

Phonep=newPhone() ;

p.setBrand("华为p40") ;

p.setPrice(6799) ;

p.setColor("天空灰") ;

System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+p.getColor()) ;

p.callPhone() ;

p.sendMsg("高圆圆") ;

}

}

private关键字的特点


/*

private关键字的特点:

1)被private修饰的成员变量/成员方法(非静态),

只能在本类中访问,外界类不能访问!

2)虽然被私有修饰的成员变量以及成员方法(非静态)不能直接访问,但是

都可以间接的通过"public"公共访问访问!

*/

//定义Demo类

classDemo{

//成员变量:类中方法外

publicintnum=10 ;

privateintnum2=20 ;

//定义一个公共的方法

publicvoidshow(){

System.out.println(num) ; //10

System.out.println(num2) ;//20

}

//其他成员方法

publicvoidmethod(){

System.out.println("method Demo") ;

System.out.println("-------------------------") ;

function() ;

}

//私有的成员方法

privatevoidfunction(){

System.out.println("function Demo") ;

}

}

//测试类

classPrivateDemo{

publicstaticvoidmain(String[] args){

//需求:访问Demo类中num和num2变量?

//创建Demo类对象

Demod =newDemo() ;

System.out.println(d.num) ;

System.out.println("---------------------------") ;

//System.out.println(d.num2) ; //num2 在 Demo 中是 private 访问控制

//要访问num2这个变量:间接访问了

d.show() ;

d.method() ;

//d.function() ; // function() 在 Demo 中是 private 访问控制

}

}

学生封装例子


/*

学生有姓名,年龄两个属性;

将姓名和年龄属性私有化,加入private,外界类不能直接使用(保证数据的安全性!)

定义一个学生类,然后在StudentTest中进行测试,成员变量赋值,打印成员信息;

封装:

一个事物的私有化(private),外界类不能直接使用,

对外需要通过公共的访问setXXX(参数)/getXXX()赋值(成员变量赋值)

获取值(获取成员变量的值)

*/

//学生类

classStudent{

//属性私有化:全部private

privateStringname ; //姓名

privateintage ; //年龄

//对外提供公共的访问方法setXXX()/getXXX():才能赋值/获取值

//1)给成员变量 name赋值

publicvoidsetName(Stringn){ //"高圆圆" n:局部变量

name=n ;

}

//获取成员变量name 的值

publicStringgetName(){

returnname ; //成员变量

}

//2)给成员变量 年龄age赋值

publicvoidsetAge(inta){//44 a:局部变量

age=a ; //44

}

publicintgetAge(){

returnage ;

}

//成员方法:学习

publicvoidstudy(){

System.out.println(name+"正在学习JavaSE") ;

}

}

//学生类的测试类

classStudentTest{

publicstaticvoidmain(String[] args){

//类名 对象名 = new 类名() ; //创建一个学生

Students=newStudent() ;

//对象名.成员变量 = 赋值;

//s.name = "高圆圆" ;//name 在 Student 中是 private 访问控制

//访问setXXX(xxx)/getXXX()

s.setName("高圆圆") ;

s.setAge(44) ;

System.out.println("该学生的姓名是:"+s.getName()+

",年龄是:"+s.getAge()) ;

//其他成员方法

s.study() ;

}

}

02一个标准类的写法加入private_this


/*

手机类:

品牌brand,价格price,颜色color--->属性加入私有修饰!

打电话callPhone(),发短信sendMsg()

在PhoneTest中进行 手机类的测试,给属性赋值,并且调用成员方法,打印信息!

(加入this:局部变量给成员变量赋值,局部变量--见名知意)

*/

//定义一个手机类

classPhone{

//成员变量

privateStringbrand ;

privateintprice ;

privateStringcolor ;

//setXXX(xx)赋值

publicvoidsetBrand(Stringbrand){ //局部变量

this.brand=brand ;

}

publicvoidsetPrice(intprice){

this.price=price ;

}

publicvoidsetColor(Stringcolor){

this.color=color ;

}

//getXXX()获取值

publicStringgetBrand(){

returnbrand ;

}

publicintgetPrice(){

returnprice ;

}

publicStringgetColor(){

returncolor ;

}

}

//测试类

classPhoneTest{

publicstaticvoidmain(String[] args){

//使用 类 对象名 = new 类名() ;

Phonep=newPhone() ;

p.setBrand("华为p40") ;

p.setPrice(4599) ;

p.setColor("翡翠绿") ;

System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+

p.getColor()) ;

}

}

学生类加入this关键代码改进


/*

学生有姓名,年龄两个属性;

将姓名和年龄属性私有化,加入private,外界类不能直接使用(保证数据的安全性!)

定义一个学生类,然后在StudentTest中进行测试,成员变量赋值,打印成员信息;

按需上面的测试:

通过setXXX(xx)给成员变量赋值,问题:变量并没有"见名知意"

给成员变量name/age进行赋值,局部变量名称也是name,age;

优化之后:成员变量 姓名name ,年龄age 都赋值不了

原因:局部变量名称 和成员变量名称一致,导致出现的问题;

Java提供了一个关键字:(局部变量名称隐藏了成员变量名称)this--->

代表当前类的对象的地址值引用!

this.成员变量名 = 局部变量名;

*/

//学生类

classStudent{

//属性私有化:全部private

privateStringname ; //姓名

privateintage ; //年龄

//对外提供公共的访问方法setXXX()/getXXX():才能赋值/获取值

//1)给成员变量 name赋值

//public void setName(String n){ //"高圆圆" n:局部变量

//name = n ;

//}

//优化

publicvoidsetName(Stringname){//"高圆圆"

//name = name ;错误的

this.name=name ;

}

//获取成员变量name 的值

publicStringgetName(){

returnname ; //成员变量

//return this.name ; //this可以省略

}

//2)给成员变量 年龄age赋值

/*

public void setAge(int a){//44 a:局部变量

age = a ; //44

}

*/

//优化

publicvoidsetAge(intage){

//age = age ;//错误的

this.age=age ;

}

publicintgetAge(){

//return this.age ;//this可以省略

returnage ;

}

//成员方法:学习

publicvoidstudy(){

System.out.println(name+"正在学习JavaSE") ;

}

}

//测试类

classStudentTest{

publicstaticvoidmain(String[] args){

//测试学生类

Students=newStudent() ;

s.setName("高圆圆") ;

s.setAge(44) ;

System.out.println(s.getName()+"---"+s.getAge()) ;

}

}

0_3成员变量和局部变量的区别


面试题


/*

面试题:(理解并去识记)

局部变量和成员变量的区别?

区别:

1)类中的书写位置不同

成员变量:在类中,方法外

局部变量:在方法定义中或者方法声明上

2)jvm内存位置不同

成员变量:在堆内存中

局部变量:在栈内存中

3)生命周期不同:

成员变量:随着对象的创建而存在,随着对象的创建完毕并且使用完

等待垃圾回收器回收(不会立即回收)而消失!

局部变量:随着方法调用而存在,随着方法调用结束而消失

4)初始化值不同:

成员变量:存在系统默认初始化,也可以显示初始化

局部变量:总之:在使用局部变量之前,必须赋值,不赋值不行!

*/

//定义一个类Variable

classVariable{

//成员变量

intnum ; //系统默认初始化就是0

publicvoidshow(Stringy){ //y

//int x = 100 ; //x 局部变量

intx ;

x=100 ;

System.out.println(x+y) ;

}

}

//测试类

classVariableDemo{

publicstaticvoidmain(String[] args){

//访问show方法

//创建Variable类对象

Variablev=newVariable() ;

System.out.println(v.num) ;

v.num=100 ;

System.out.println(v.num) ;

v.show("hello") ;

}

}

04引入构造方法


/*

一个类的成员:

成员变量

成员方法(非静态)

构造方法:

什么是构造方法?

1)方法名和类名一致

2)没有具体返回值类型

3)连void都没有

构造方法是可以重载!

构造方法的作用:

给类的成员进行数据初始化!

注意事项:

1)一个类中,如果没有任何构造方法,那么系统(jvm)自动会给我们提供无参构造方法!

2)一个类中,只提供有参构造方法,那么系统不会无参构造方法,此时,建议我们永远给出无参构造方法!否则,就出现问题!

创建对象的时候固定格式:

类名 对象名 = new 类名() ;

*/

classStudent{//学生类

//带两个参数

privateStringname ;//姓名

privateintage ; //年龄

/*

1)方法名和类名一致

2)没有具体返回值类型

3)连void都没有

*/

//无参构造方法

/*

public Student(){

System.out.println("这是Student的无参构造方法") ;

}

*/

//带有一个String类型的参数的构造方法

publicStudent(Stringname){ //姓名:局部变量---成员变量

System.out.println("这是一个带有String参数的构造方法") ;

this.name=name ;

}

//带有String类型,以及int类型的构造方法

publicStudent(Stringname,intage){

System.out.println("这是一个带两个参数的构造方法") ;

}

}

//测试类

classConstructorDemo{

publicstaticvoidmain(String[] args){

//创建一个学生类对象

Students=newStudent();

System.out.println(s) ;//堆内存地址

System.out.println("-------------------") ;

Students2=newStudent("高圆圆") ;

System.out.println(s2) ;//新的堆内存空间

System.out.println("-------------------") ;

//在创建第三个学生对象

Students3=newStudent("高圆圆",44) ;

System.out.println(s3) ;

}

}

手机类加入构造方法的优化


/*

手机类:

品牌brand,价格price,颜色color--->属性加入私有修饰!

打电话callPhone(),发短信sendMsg()

在PhoneTest中进行 手机类的测试,给属性赋值,并且调用成员方法,打印信息!

(加入this:局部变量给成员变量赋值,局部变量--见名知意)

一个标准类的写法:

类的成员

成员变量:属性私有化

成员方法:公共访问setXXX(xx)/getXXX()

构造方法:无参构造方法:永远给出

有参构造方法

*/

//定义一个手机类

classPhone{

//成员变量

privateStringbrand ;

privateintprice ;

privateStringcolor ;

//无参构造方法

publicPhone(){

}

//有参构造方法

publicPhone(Stringbrand,intprice ,Stringcolor){ //"Iphone14",12999,"土豪金"

//局部变量给成员变量赋值

this.brand=brand ;

this.price=price ;

this.color=color ;

}

//setXXX(xx)赋值

publicvoidsetBrand(Stringbrand){ //局部变量

this.brand=brand ;

}

publicvoidsetPrice(intprice){

this.price=price ;

}

publicvoidsetColor(Stringcolor){

this.color=color ;

}

//getXXX()获取值

publicStringgetBrand(){

returnbrand ;

}

publicintgetPrice(){

returnprice ;

}

publicStringgetColor(){

returncolor ;

}

}

//测试类

classPhoneTest{

publicstaticvoidmain(String[] args){

//使用 类 对象名 = new 类名() ;

//无参构造方法+setXXX(xx)+getXXX()

Phonep=newPhone() ;

p.setBrand("华为p40") ;

p.setPrice(4599) ;

p.setColor("翡翠绿") ;

System.out.println(p.getBrand()+"---"+p.getPrice()+"---"+

p.getColor()) ;

System.out.println("-----------------------") ;

//方式2:手机类的有参构造方法+getXXX()

/*

public Phone(String brand,int price ,String color){

//局部变量给成员变量赋值

this.brand = brand ;

this.price = price ;

this.color = color ;

}

*/

Phonep2=newPhone("Ipho

ne14",12999,"土豪金") ;

System.out.println(p2.getBrand()+"---"+p2.getPrice()+"---"+

p2.getColor()) ;

}

}

day12


static静态关键字


packagecom.qf.static_01;

/**

* 关于static关键字--->被多个对象"共享,共用"的意思

*

*

* 特点:

* 1)被static修饰的成员(变量/方法)随着类的加载而加载,优先于对象存在! (对象创建: 类名 对象名 = new 类名() ;)

* 某个类要先被编译产生-->类名.class--->类在运行的时候,加载过程要将静态的成员都先进入方法区的静态区中!

* 2)static和this不能共存!

* this:代表是当前类对象的地址值引用---说明对象创建完毕,才能使用this.变量名 -->访问成员变量 (对象成员)

* static:随着类的加载而加载,被static修饰的成员--->"类成员"

* 3)如果有一个变量体现出被共享,被共用--->此时用"static"修饰

*

* 举例:

* 水杯中的水 (不行)

* 饮水机的水(可以被共享)

* 4)访问方式:(必须记住)

* 类成员--->被static修饰的,特有访问 方式

* 类名.变量名; //在访问本类中静态变量

* 类名.方法名() ;//在访问本类中的静态方法

*

* 注意:

* 我们所说的成员变量/成员方法---->默认 非静态的!

*

*/

//定义一个Demo类

classDemo{

//定义一个非静态成员变量

publicintnum=100 ;

//静态的变量(静态成员变量)

publicstaticintnum2=50 ;

//非静态的成员方法

publicvoidmethod(){

System.out.println("method Demo...");

}

//静态的成员方法(类方法)

publicstaticvoidfunction(){

System.out.println("function Demo...");

// method() ; //这个方法非静态的

// System.out.println(num);

// System.out.println(num2) ;

}

}

//测试类

publicclassStaticDemo {

publicstaticvoidmain(String[] args) {

//需求:要访问Demo类中num和num2这个变量?

//创建Demo类对象

Demod=newDemo() ;

System.out.println(d.num) ;

//System.out.println(d.num2) ; //可以访问,不建议这种方式

System.out.println(Demo.num2);//静态--都被类名访问

System.out.println("------------------------------------") ;

//访问method方法

d.method();

// d.function() ;//可以访问,不建议这种方式

Demo.function(); //访问静态方法

//jdk提供的Math:针对数学运算的工具类

//double random = Math.random();//静态发那个发

}

}

static的使用注意事项


packagecom.qf.static_01;

/**

*静态static的使用注意事项:

* 1)非静态的成员方法里面,皆可以访问静态的变量/方法,也可以访问非静态的变量/方法!

*

* 2)静态的方法只能访问静态的成员,不能访问静态的

*

*

* 记住: 静态只能访问静态!

*/

//定义类Code

classCode{

//非静态变量

publicintx=10 ;

//静态变量:

publicstaticinty=20 ;

//非静态的成员方法

publicvoidshow(){

//访问x

System.out.println(x) ;

//静态变量

System.out.println(y) ;

}

//静态方法

publicstaticvoidfunction(){

System.out.println("function Code...");

}

//静态的方法

publicstaticvoidmethod() {

//访问非静态变量x

// System.out.println(x) ;

//访问静态的变量y

System.out.println(y);

System.out.println("-------------下面调用方法了--------------");

//show() ; //非静态方法

function();//静态方法

}

}

//测试类

publicclassStaticDemo2 {

publicstaticvoidmain(String[] args) {

//创建Code类对象

Codecode=newCode() ;

code.show();

System.out.println("------------------------------");

//直接调用静态方法

Code.method();

Code.function();

System.out.println("------------------------------");

//int add = sum(10,20) ;

}

/*public static int sum(int a,int b){

return a+b ;

}*/

}

static的举例


packagecom.qf.static_01;

/**

*静态static的使用注意事项:

* 1)非静态的成员方法里面,皆可以访问静态的变量/方法,也可以访问非静态的变量/方法!

*

* 2)静态的方法只能访问静态的成员,不能访问静态的

*

*

* 记住: 静态只能访问静态!

*/

//定义类Code

classCode{

//非静态变量

publicintx=10 ;

//静态变量:

publicstaticinty=20 ;

//非静态的成员方法

publicvoidshow(){

//访问x

System.out.println(x) ;

//静态变量

System.out.println(y) ;

}

//静态方法

publicstaticvoidfunction(){

System.out.println("function Code...");

}

//静态的方法

publicstaticvoidmethod() {

//访问非静态变量x

// System.out.println(x) ;

//访问静态的变量y

System.out.println(y);

System.out.println("-------------下面调用方法了--------------");

//show() ; //非静态方法

function();//静态方法

}

}

//测试类

publicclassStaticDemo2 {

publicstaticvoidmain(String[] args) {

//创建Code类对象

Codecode=newCode() ;

code.show();

System.out.println("------------------------------");

//直接调用静态方法

Code.method();

Code.function();

System.out.println("------------------------------");

//int add = sum(10,20) ;

}

/*public static int sum(int a,int b){

return a+b ;

}*/

}

package com.qf.static_02;

/**

* 定义数组工具类ArrayTool

* 工具类中方法都是静态的,而且构造方法私有的

*

*/

public class ArrayTool {

//提供无参构造方法,无参构造私有化---目的就是为了让外界类不能创建对象!

private ArrayTool(){}

//遍历功能--->全部加入static

public static void printArray(int[] array){

System.out.print("[") ;

//遍历数组

for (int i = 0; i < array.length; i++) {

if(i == array.length-1){

System.out.println(array[i]+"]");

}else{

System.out.print(array[i]+", ");

}

}

}

}

static例子的改写


packagecom.qf.static_03;

importjava.lang.reflect.Array;

/**

* 需求:

* 已知一个数组,静态初始化,给数组中加入遍历功能,进行测试!

* 从最早开始定义方法--->面向对象的访问方式的过程!

*

*

* 自定义一个类工具类,构造方法私有化,对外提供静态的功能,对这个工具类产生 "文档说明书"

* 找到ArrayTool.java文件所在的目录

* 在dos窗口中输入指令

* javadoc -d 目录名称 -author -version java源文件名称 (前提条件是这个ArrayTool类必须是public修饰)

*

* 举例:

* javadoc -d doc -author -version ArrayTool.java

*

*

*

*/

//测试类

publicclassArrayTest {

publicstaticvoidmain(String[] args) {

//已知一个数组,静态初始化

int[] arr= {54,87,29,32,13} ;

//调用ArrayTool类的所有静态功能

intmax=ArrayTool.getArrayMax(arr);

System.out.println("最大值是:"+max);

System.out.println("------------------------------");

ArrayTool.bubleSort(arr) ;

//遍历

ArrayTool.printArray(arr );

System.out.println("-------------------------------");

ArrayTool.reverseArray(arr);

//遍历

ArrayTool.printArray(arr);

System.out.println("--------------------------------");

//逆序值,查询13这个元素第一次出现的角标

intindex=ArrayTool.getIndex(arr, 13);

System.out.println(index);

intindex2=ArrayTool.getIndex(arr,300) ;

System.out.println(index2);

}

}

packagecom.qf.static_03;

/**

* ArrayTool这个类是自定义针对数组操作的工具类

* 里面提供了数组遍历,求数组最值,查询指定元素第一次索引值,逆序,冒泡排序等等这些功能

* @author 高圆圆

* @version V1.0

* */

publicclassArrayTool {

//提供无参构造方法,无参构造私有化---目的就是为了让外界类不能创建对象!

privateArrayTool(){}

/**

* 这功能是对数组进行遍历的功能,

* 最终数组以[元素1, 元素2, 元素3, ...元素n]形式出现

* @param array 传递的数组

*

* */

public static voidprintArray(int[] array){

System.out.print("[") ;

//遍历数组

for (inti=0; i<array.length; i++) {

if(i==array.length-1){

System.out.println(array[i]+"]");

}else{

System.out.print(array[i]+", ");

}

}

}

/**

*该方法是针对数组的求最大值的功能

* @param array 指定数组

* @return 返回值是表示数组中出现的最大值

* */

publicstaticintgetArrayMax(int[] array){

//定义中参照物

intmax= array[0] ;

for(intx=1 ; x<array.length ;x++){

if(array[x] >max){

max=array[x] ;

}

}

return max ;

}

/**

* 该功能是查询数组中的元素第一次出现索引值

* @param array 需要在指定数组中查询

* @param key 要查询指定的数组中的元素

* */

publicstaticintgetIndex(int[] array,intkey){

//假设

intindex=-1 ;

//遍历数组

for(intx=0 ; x<array.length ; x++){

if(key==array[x]){

index=x ;

break ;

}

}

return index ;

}

/***

* 该功能是针对数组进行冒泡排序,两两比较,将较大的值往后放,

* 第一次比较完毕,最大值出现在最大索引处!

* @param array 要输入指定数组进行冒泡排序

*/

publicstaticvoidbubleSort(int[] array){

for(intx=0 ;x<array.length-1 ;x++){

for(inty=0 ; y<array.length-1-x;y++){

if(array[y] >array[y+1]){

inttemp=array[y] ;

array[y] =array[y+1] ;

array[y+1] =temp ;

}

}

}

}

/***

* 该功能是将数组逆序,将第一个元素和最后一个元素进行互换,第二个元素和倒数第二个元素互换

* 依次这样操作,将数组逆序

* @param array 传入指定数组进行逆序

*/

publicstaticvoidreverseArray(int[] array){

for(intstart=0 ,end=array.length-1 ;start<end ;start++,end--){

inttemp=array[start] ; //array[0]

array[start] =array[end] ; //array[array.lengtt-1]

array[end] =temp ;

}

}

}

java中的代码块


packagecom.qf.code_04;

importcom.sun.xml.internal.ws.addressing.WsaActionUtil;

/**

*什么是Java中的代码块?

*

* Java中的代码块是一个{}包裹起来的内容!

* 分类:

* 局部代码块--->方法定义中 作用:限定局部变量的生命周期

* 构造代码块--->类的成员位置定义的{}

* 作用:在执行构造方法之前,如果存在构造代码块,先执行构造代码块,

* 然后在执行构造方法 ,就是给数据进行初始化的!

* 静态代码块--->类的成员位置定义的

* static{

*

* }

* 特点:跟类相关,类一加载,先执行,而且只执行一次(因为类就加载一次)

* 优先级最大

*

*

*

* 优先级:

* 静态代码块 > 构造代码块 > 构造方法!

*

*/

//定义一个Code类

classCode {

//静态代码块

static{

intx=1000 ;

System.out.println(x) ;

}

publicCode() {

System.out.println("code的无参构造方法");

}

//构造代码块

{

intx=100 ;

System.out.println(x) ;

}

//构造代码块

{

inty=200;

System.out.println(y);

}

//有参构造

publicCode(Stringname){

System.out.println("code"+name) ;

}

static{

inty=2000 ;

System.out.println(y) ;

}

}

//测试类

publicclassCodeDemo {

publicstaticvoidmain(String[] args) {

//方法中 {},局部代码块

/* {

int x = 100 ;

System.out.println(x) ;

}*/

//System.out.println(x);

// System.out.println("------------------------------") ;

//创建Code类的对象---无参构造方法创建

Codecode=newCode() ;

System.out.println("------------------") ;

Codecode2=newCode("helloworld") ;

}

}

代码块的面试题


packagecom.qf.code_04;

/**

*看程序,写结果

*

* 优先级

* 静态代码块 > 构造代码块 > 构造方法

*/

classStudent{

static{

System.out.println("Student的静态代码块1");

}

publicStudent(){

System.out.println("Student的无参构造方法");

}

{

System.out.println("student的构造代码块1");

}

publicStudent(Stringname){

System.out.println("Student的有参构造方法"+name);

}

static{

System.out.println("Student的静态代码块2");

}

{

System.out.println("student的构造代码块2");

}

}

publicclassMainTest {

static{

System.out.println("MainTest的静态代码块");

}

publicstaticvoidmain(String[] args) {

Students=newStudent() ;

Students2=newStudent("高圆圆") ;

}

}

继承(重点)


继承的概念


packagecom.qf.extends_05;

/**

* 继承的概念:

* 将多个类的共性内容抽取到一个独立的类中,这个独立的类和这多个类产生一种关系 "继承"

*

* 继承的格式:

* class 父类名{}

* class 子类名 extends 父类名{}

*

* 继承的好处:

* 1)可以提高代码的复用性

* 2)可以增强代码的后期维护

* 3)类与的类关系:继承关系 是多态的前提条件!

*

*

* 使用"继承"的时机:什么时候使用继承?

*

* class A{

* public void show(){}

* public void show2(){}

* }

* class B{

* //public void show(){}

* public void show3(){}

* }

*

* ---->优化 class B extends A{}

* 不能为了使用部分功能就使用继承!

* 使用继承的前提条件:

* 如果一个类A是类B一种,或者是类B是类A的一种,才能使用继承,继承的核心思想体现出一种"is a"的关系

* 举例:

* 水果:

* 橘子

* 苹果

* 西瓜..

* 人:

* 工人

* 学生

* 军人

* 老师....

*

* 实际开发中:

* 所有的开发原则都必须遵循 "低耦合,高内聚"

*

* 耦合:类和类的关系越少越好,耦合性只能降低,不能避免!

* 内聚:解决某件事情(功能)的执行力!(一个类能够完成的尽量一个类完成,不能产生过多关系!)

*

*/

//没有使用继承之前

//学生类

/*class Student{

//学生要学习

public void study(){

System.out.println("任何人都要学习");

}

//学累了就要休息

public void sleep(){

System.out.println("学习困了就需要休息");

}

}

//老师类

class Teacher{

//学习

//学生要学习

public void study(){

System.out.println("任何人都要学习");

}

//学累了就要休息

public void sleep(){

System.out.println("学习困了就需要休息");

}

}*/

//将共性内容抽取到独立类中

//使用继承

classPerson{ //人

//学生要学习

publicvoidstudy(){

System.out.println("任何人都要学习");

}

//学累了就要休息

public voidsleep(){

System.out.println("学习困了就需要休息");

}

}

//定义学生类

classStudentextends Person{}

//定义老师类

classTeacherextends Person{}

//测试类

publicclassExcetendsDemo {

publicstaticvoidmain(String[] args) {

//测试

//创建学生类对象

Students=newStudent() ;

s.study();

s.sleep();

System.out.println("--------------------------------") ;

//创建老师类对象

Teacher t=newTeacher() ;

t.study() ;

t.sleep() ;

}

}

继承的特点


packagecom.qf.extends_05;

/**

* 继承的特点:

* 1)在Java语言中,类与类的关系,只支持单继承 (类是Java中最基本的单元)

* 举例:

* class Fu{}

* class Fu2{}

* class Zi extends Fu,Fu2{} 这种写法错误格式

* 2)类与类之间虽然不支持多继承,但是可以多层继承!

*

*/

//爷爷

classGrandFather{ //在Java中最顶层的类:Object(所有类的父类) ,可以省略不写!

publicvoidmethod(){

System.out.println("我是爷爷");

}

}

//父类

classFatherextendsGrandFather{

publicvoidshow(){

System.out.println("我是老子");

}

}

/*class Mother{

}*/

//子类

//class Son extends Father,Mother{} //多继承(类的关系,Java不支持!)

classSonextendsFather{

publicvoidfunction(){

System.out.println("function Son");

}

}

//测试类

publicclassExtendsDemo2 {

publicstaticvoidmain(String[] args) {

//创建具体的子类

Sons=newSon() ;

s.function(); //访问自己的功能

s.show(); //继承 父类的功能

s.method(); //间接继承了他爷爷的功能

}

}

继承的注意事项


packagecom.qf.extends_05;

/**

* 继承的注意事项:

* 1)子类继承父类,是可以继承父类所有的东西,只不过父类的私有的属性以及方法只能在本类中访问

*子类是不能直接访问到的,但是可以间接的通过公共方法来访问!

* 2)子类继承父类,不能继承父类的构造方法(无参/有参构造),可以通过 "super"来访问父类的构造方法!

*

*/

//父类

classFu{

//私有的

privateintnum=100 ;

//非私有的

publicintnum2=200 ;

//定义一个成员方法

publicvoidshow(){

System.out.println(num) ;

System.out.println(num2) ;

}

//私有方法

privatevoidmethod(){

System.out.println("method Fu...");

}

//非私有

publicvoidmySelfMethod(){

method(); //调用了私有方法

}

}

//子类

classZiextends Fu{

//子类的成员方法

publicvoidfunction(){

System.out.println(num2);

// System.out.println(num);

}

}

//测试类

publicclassExtendsDemo3 {

publicstaticvoidmain(String[] args) {

//创建Zi类对象

Ziz=newZi() ;

z.function(); //使用自己的成员方法

z.show(); //继承父类的, 父类的show方法里面有一个父类私有属性

//z.method();//父类的私有方法,不能直接访问

System.out.println("------------------------");

z.mySelfMethod();

}

}

继承关系中的成员问题


packagecom.qf.extends_06;

/**

*

* 继承关系中成员问题:

* 一个类的成员:

* 成员变量

* 成员方法

* 构造方法

*

*

* 1)子类继承父类,子类中 成员变量如果父类中的成员变量名称不一致的情况:比较简单,分别访问即可!

* 2)子类继承父类,如果子类的成员变量名称和父类的成员变量名称一致,如何访问呢?

*

* a)先在子类的局部位置(子类的成员方法中定义变量:局部变量)找,如果存在,就使用

* b)如果子类的局部位置没有,然后才在子类的成员位置找,如果存在,就使用

* c)如果子类的成员位置没有,然后在父类的成员位置找,如果存在,就使用

* d)如果父类的成员位置也没有,说明当前没有这个变量,就访问报错!

*

* 一句话:就近原则!

*/

//父类

classFu{

//父类的成员变量

intnum=20 ;

}

//定义一个子类

classZiextends Fu{

//子类的成员变量

//int num2 = 30 ;

intnum=100 ;

//子类的成员方法

publicvoidshow(){

intnum=30 ; //局部变量

System.out.println(num) ;

//System.out.println(num2);

}

}

//测试类

publicclassExtendsDemo4 {

publicstaticvoidmain(String[] args) {

//创建子类对象

Ziz=newZi() ;

z.show();

}

}

继承关系中: 子类继承父类,子类如何访问父类的构造方法?


packagecom.qf.extends_06;

/**

* 继承关系中:

* 子类继承父类,子类如何访问父类的构造方法?

* 通过super关键字

*

* 1)子类继承父类,不能继承父类的构造方法,但是可以通过super访问,子类的所有构造方法默认访问父类的无参构造方法!

* 子类的构造方法的第一句话:都有super() ; 访问父类的无参构造方法

* 原因:

* 子类继承父类,可能用到父类的属性(成员变量)这些数据,必须让父类先初始化,然后子类才能初始化(构造方法,就是给数据初始化的)

* 这种过程----继承中 "分层初始化"

* 2)永远建议把父类的无参构造方法给出来,可能户导致子类的构造方法报错!

*

*/

//定义一个父类

classFu3{

//假设:姓名,年龄,性别...属性(成员变量)

//父类给一个无参构造方法

publicFu3(){

System.out.println("这是Fu3的无参构造方法");

}

/*public Fu3(String name){

System.out.println("Fu3的有参构造方法,"+name);

}*/

}

//子类

classZi3extends Fu3{

//子类的无参构造方法

publicZi3(){

// super() ;//可以隐藏不写

System.out.println("Zi3的无参构造方法");

//super() ; 放在后面,可能初始化多次,jvm编译不让通过! 必须在第一句话

}

//子类的有参构造方法

publicZi3(Stringname){

//super() ;//可以隐藏不写

System.out.println("Zi3的有参构造方法,"+name);

}

}

//测试类

publicclassExtendsDemo5 {

publicstaticvoidmain(String[] args) {

//通过子类的无参构造方法,创建子类对象

Zi3z=newZi3() ;

System.out.println("--------------------") ;

//通过子类的有参构造放,创建子类对象

Zi3zz=newZi3("hello") ;

}

}

继承关系中的构造方法的注意事项


packagecom.qf.extends_06;

/**

* 继承关系中的构造方法的注意事项

*

* 子类继承父类,子类的所有构造方法第一句话都隐藏了默认 super() ;访问父类的无参构造方法,只存在父类的有参构造方法

* 那么,如果父类中并没有给出无参构造方法,子类会出现什么情况?如何解决?

*

* 子类的所有构造方法都会报错!默认都要访问父类无参构造方法(默认机制)

* 解决方案:

* 1)自己手动给出父类的无参构造方法(推荐)

* 2)不给出父类的无参构造方法,怎么解决?

* 让子类的所有构造方法都直接来访问父类的有参构造方法,只要父类初始化即可!

* 3)所有的子类的构造方法只要有一个让父类初始化即可!

* 在子类的无参构造方法中第一句话: this(xxx) ; 访问本类(子类)的有参构造方法

* 在通过子类的有参构造方法的第一句话:super(xxx) ;访问父类的有构造方法---->父类先初始化完毕完毕

*

*

* 实际开发中:(写继承代码的时候)

* 子类继承父类,子类的无参构造方法访问父类的无参!

* 子类的有参构造方法访问父类的有参!

*/

//定义一个父类

classFather{

//手动给出Father的无参

/* public Father(){

System.out.println("Father的无参构造方法");

}*/

//Facther的有参构造

publicFather(intnum){

System.out.println("Father的有参构造方法:"+num) ;

}

}

//定义一个子类

classSonextends Father{

//Son类的无参构造方法

publicSon(){

super(100) ; //访问父类的有参构造方法

//this(100) ;//访问本类的有参构造方法

System.out.println("Son的无参构造方法");

}

//Son的有参构造方法

public Son(intnum){

//super(20) ; //访问父类的有参构造方法

this() ;//访问本类无参构造方法

System.out.println("Son的有参构造方法:"+num);

}

}

//测试类

publicclassExtendsDemo6 {

publicstaticvoidmain(String[] args) {

// Son s = new Son() ;

Sons=newSon(50) ;

}

}

继承的面试题


packagecom.qf.extends_06;

/**

* 面试题

*看程序,补全代码,分别在控制台打印-- 30 20 10

* super:代表的是父类的空间标识(父类对象的地址值引用)

* this:代表本类对象的地址值引用

*/

classFu2{

intnum=10 ;

}

classZi2extends Fu2{

intnum=20 ;

publicvoidshow(){

intnum=30;

//补全代码

System.out.println(num) ;

System.out.println(this.num); //访问的是本类的成员变量

System.out.println(super.num); //访问父类的成员变量

}

}

//测试类

publicclassExtendsTest {

publicstaticvoidmain(String[] args) {

Zi2z=newZi2() ;

z.show();

}

}

看程序写结果(面试题)


packagecom.qf.extends_06;

/**

* 看程序,写结果

* 考点:

* 代码块的优先级

* 静态代码块 > 构造代码块 > 构造方法

* 继承关系问题

* 子类的所有构造方法默认父类的无参构造方法,目的就是让父类初始化的,然后在子类初始化!

*/

classPerson{

publicPerson(){

System.out.println("这是Person类的无参构造方法");

}

static{

System.out.println("Person的静态代码块");

}

{

System.out.println("Person的构造代码块");

}

}

//子类

classStudentextends Person{

publicStudent(){

//super();

System.out.println("Student的无参构造方法");

}

publicStudent(Stringname){

System.out.println("Student的有参构造方法");

}

{

System.out.println("Student的构造代码块");

}

static{

System.out.println("Student的静态代码块");

}

}

publicclassExtendsTest2 {

publicstaticvoidmain(String[] args) {

Students=newStudent() ;

Students2=newStudent("高圆圆") ;

}

}

继承的例题


packagecom.qf.extends_07;

/**

* 猫狗案例---继承版

*

* 猫和狗--都有姓名,年龄,毛色

* 猫和狗---吃和睡的功能

*

* 现在使用面向对象的方式,加入继承,在AnimalTest测试猫和狗

* 分析:

* 猫类--描述 猫事物

* 属性:name,age,color---私有化

* setXXX(xx)/getXXX()

* 行为:eat(),sleep() , 特有功能:catchMouse()

* 狗类--描述 狗事物

* 属性 :name,age,color---私有化

* setXXX(xx)/getXXX()

* 行为:eat(),sleep(),特有功能:lookDoor()

*

* 将猫和狗的共性内容---抽取到一个独立的类中 "动物类"---描述动物的

* 属性:name,age,color---私有化

* setXXX(xx)/getXXX()

* 行为:eat(),sleep()

*/

//测试类

publicclassAnimalTest {

publicstaticvoidmain(String[] args) {

//创建一只狗

//无参构造方法+ setXXX(xx)/getXXX()

Dogd=newDog() ;

d.setName("拉布拉多") ;

d.setAge(5) ;

d.setColor("棕色") ;

System.out.println(d.getName()+"---"+d.getAge()+"---"+d.getColor());

d.eat();

d.sleep();

d.lookDoor();

System.out.println("--------------------------------") ;

//方式2:有参构造方法直接赋值+getXXX()

Dogd2=newDog("二哈",3,"白色") ;

System.out.println(d2.getName()+"---"+d2.getAge()+"---"+d2.getColor());

d2.eat();

d2.sleep();

d2.lookDoor();

}

}

packagecom.qf.extends_07;

/**

* 动物类

* 属性:name,age,color---私有化

* setXXX(xx)/getXXX()

* 行为:eat(),sleep()

*/

publicclassAnimal {

//属性--私有化

privateStringname ; //姓名

privateintage ; //年龄

privateStringcolor ; //毛色

//无参构造方法

//alt+ins--->constructor--->select none

publicAnimal() {

}

//有参构造方法

//alt+ins--->constructor--->cltr+a--->回车

publicAnimal(Stringname, intage, Stringcolor) {//"哆啦A梦",5,"蓝色"

this.name=name;

this.age=age;

this.color=color;

}

//公共访问方法setXXX(xx)/getXXX()

//alt+ins--->getter and setter--->altr+a--->回车

publicStringgetName() {

returnname;

}

publicvoidsetName(Stringname) {

this.name=name;

}

publicintgetAge() {

returnage;

}

publicvoidsetAge(intage) {

this.age=age;

}

publicStringgetColor() {

returncolor;

}

publicvoidsetColor(Stringcolor) {

this.color=color;

}

//其他成员方法

publicvoideat(){

System.out.println("动物都需要吃饭") ;

}

publicvoidsleep(){

System.out.println("动物累了就需要休息");

}

}

packagecom.qf.extends_07;

/**

* 猫类

*/

publicclassCat extendsAnimal{

//猫的无参构造方法

/* public Cat(){ //Cat cat = new Cat() ;

//super();

}*/

//猫的有参构造方法

/* public Cat(String name,int age,String color){ //Cat c = new Cat("哆啦A梦",5,"蓝色");

super(name,age,color); //访问父类的有参构造方法

}*/

//alt+ins--->constructor--->将两个构造方法全部提供

publicCat() {

}

publicCat(Stringname, intage, Stringcolor) {

super(name, age, color);

}

//猫的特有功能

publicvoidcatchMouse(){

System.out.println("猫会抓老鼠");

}

}

packagecom.qf.extends_07;

/**

* 狗类

*/

publicclassDog extendsAnimal{

//无参/有参构造方法

publicDog() {

super();

}

publicDog(Stringname, intage, Stringcolor) {

super(name, age, color);

}

//狗的特有功能

publicvoidlookDoor(){

System.out.println("狗会看门");

}

}

面向对象的例题


packagecom.qf.test_08;

/**

* .(面向对象基础)写一个Worker 类,并创建多个Worker 对象。

* 1) 为Worker 类添加三个属性,1)String 类型的name,表示工人的姓名;

* int 类型的age,表示工人的年龄;3)double 类型的salary,表示工人

* 的工资。

* 2) 为Worker 类添加两个work 方法,一个无参,另一个带整数参数,表示

* 工人工作的时间(为多少小时)。

*

*

* Worker如下的属性的类型以及构造方法相关的参数

* name:String

* age:int

* salary:double

* Worker()

* work(hours:int)

*

* 在测试类中进行测试 工人类(属性私有化)

*/

publicclassTest1 {

publicstaticvoidmain(String[] args) {

//无参构造+setxxx(xx)/getXX()

Workerworker=newWorker() ;

worker.setName("唐伯虎9527");

worker.setAge(30) ;

worker.setSalary(10000.0) ;

worker.work(25);

System.out.println("---------------------");

//有参构造方法直接赋值

Workerw2=newWorker("秋香",25,8000.0) ;

w2.work(8);

}

}

packagecom.qf.test_08;

/**

* 定义一个工人类

*/

publicclassWorker {

privateStringname ; //姓名

privateintage ; //年龄

privatedoublesalary ;//工资

//定义无参构造方法

publicWorker(){

}

publicWorker(Stringname,intage, doublesalary){

this.name=name ;

this.age=age ;

this.salary=salary ;

}

publicStringgetName() {

returnname;

}

publicvoidsetName(Stringname) {

this.name=name;

}

publicintgetAge() {

returnage;

}

publicvoidsetAge(intage) {

this.age=age;

}

publicdoublegetSalary() {

returnsalary;

}

publicvoidsetSalary(doublesalary) {

this.salary=salary;

}

//Worker 类添加两个work 方法,一个无参,另一个带整数参数,表示

// 工人工作的时间(为多少小时)。

publicvoidwork(inthours){

System.out.println(name+",年龄是"+age+",工资是:"+salary+",已经工作了"+hours);

}

}

day13


晨写


#晨写

##1.静态代码块,构造代码块,构造方法的优先级

```markdown

优先级

静态代码块>构造代码块>构造方法

```

##2.static关键字的特点

```markdown

1.被static修饰的变量/方法,随着类的加载而加载,优先于对象存在

2.staitc关键字不能和this共存

3.具有"共享,共用"的意思

4.特有访问方法,使用类名访问 (类成员)

类名.变量名;

类名.方法名();

```

##3.什么是继承?继承的好处

```markdown

继承:

将多个类的共性内容抽取到一个独立的类中,让这个独立的类和这多个类产生一种关系,"extends"

好处:

1)可以提高代码的复用性

2)可以增强代码的维护性

3)类与类的关系,是多态前提条件!

所有开发原则必须遵循"低耦合,高内聚"

```

##4.继承的特点

```markdown

特点:

1)类与类之间,在Java语言中,只支持单继承,不支持多继承

2)不支持多继承.可以多层继承

```

##5.继承中,子类和父类出现的成员变量名称一致的情况,如何访问

```markdown

继承关系中,成员变量一致:

1)在子类的局部位置先找,如果有就使用;

2)如果子类局部位置没有,会在子类的成员位置中找,有就使用;

3)如果子类的成员位置也没有,会在父类的成员位置找,有就使用

4)如果父类中的成员位置也没有,访问了不存在的变量(编译报错)

classFu{}

classZiextendsFu{}

//测试

Ziz=newZi() ;

```

##6.继承中,子类继承父类,构造方法如何访问?

```markdown

子类继承父类,构造方法的访问:

构造方法是不能继承的!

构造方法目的为了给类的成员进行初始化;

继承关系中,子类继承父类,默认所有的子类的构造方法通过super() ;访问父类的构造方法

建议:描述一个事物,使用"类"来进行定义,永远给无参构造方法;

如果没有给出父类的构造方法,但是给了父类的有参构造方法,那么默认子类的所有构造方法都会报错!

解决方案:

1)要么直接手动给出父类无参

2)假设不给给出父类无参构造方法,直接让子类的所有构造方法通过super(xxx);来访问父类的有参

3)子类所有的构造方法中只要有一个能够父类初始化!

```

```java

classFu{

//公共的属性

publicFu(){}

}

classZiextendsFu{

publicZi(xxxx){

//子类的有参构造方法

}

}

```

---

---

#今日内容

##1.作业相关

##2.继承成员方法的访问

```

成员方法:

是否带参

是否有返回值

```

##3.方法重写:override /overload方法重载区别?--面试题

##4.引入关键字----final(特点:记住)

```

final特点

```

##5.多态(重点)

```

概念

能够使用多态的前提条件

多态成员访问特点

成员变量

成员方法:非静态的

构造方法:分层初始化(因为继承关系)

多态的好处:

多态的弊端:

```

-----

----

##面试题

###方法重写和方法重载的区别

```markdown

override和overload的区别

方法重载:

在定义方法的时候,为了提高功能的扩展性,同一个方法名,可以使用不同的参数进行传递!

方法名相同,参数列表不同,与返回值无关!

参数列表不同:

1)参数个数

2)参数类型

3)类型的先后顺序

方法重写:

是在继承关系中使用的;

子类继承父类,子类的功能想沿用父类的功能,同时使用自己的功能,子类出现了和父类一模一样的方法,--方法重写(覆盖/复写)

子类继承父类,如果要重写父类的功能,访问权限不能够更低,最起码跟父类的成员方法一致,要么永远public!

举例:

人:

eat() 吃的功能

员工:

work() 都需要工作

程序员也是员工 ---->日日夜夜敲带

项目奖经理也是员工---->吃饭喝酒谈项目

```

###this和super的区别

```markdown

概念区别

this:代表是当前类对象的地址值引用

super:代表父类的对象的地址值引用(父类的空间标识)

成员访问的区别:

this.变量名; 访问本类的成员变量

super.变量名; 访问父类的成员变量

this.方法名() ; 访问本类成员方法

super.方法名() ;访问的父类的成员方法

this() ; 访问本类的无参构造方法

this(xxx); 访问的本类的有参构造方法

super() ;访问的是父类的无参构造方法

super(xxx) ; 访问的是父类的有参构造方法

```

###final修饰基本数据类型和修饰引用数据类型的区别?

```markdown

final修饰的引用数据类型,当前不能在开辟堆内存(不能重新new),里面的成员变量依然可以进行赋值

final修饰的基本数据类型,基本数据数据值不能在改变!

```

###final,finalize,finally的区别?

```markdown

final是一个状态修饰符.最终的,无法更改的!

修饰类,该类不能被继承

修饰成员方法,该方法不能被重写

修饰变量,此时变量是一个常量;

finalize:是一个方法名,是后面jvm当前确定堆内存中对象没有更多引用的时候,来通过垃圾器来调用进行回

收的方法!

finally:是关键字,是后面Java中去处理"异常"的一种格式:捕获异常

标准格式

try{

//可能出现问题代码

}catch(异常类名变量名){

处理异常

}finally{

//释放相关的系统资源 (后面学习IO流,读取文件/写文件等等)

}

```

变量--->成员变量/局部变量什么时候将一个变量定义为成员变量?


packagecom.qf.variable_02;

/**

* 变量--->成员变量/局部变量

* 什么时候将一个变量定义为成员变量?

*

* 需求:

* 定义一个类,定义成员方法,对两个数据求和!

*

* 将一个变量定义为成员变量的时机:

* 如果这个变量能够描述现实世界事物的属性--->定义为成员变量,否则都是"局部变量"

*/

classDemo{

//成员变量

/*

int a ;

int b ;

//定义一个成员方法

public int sum(){

return a + b ;

}

*/

publicintsum(inta,intb){

return a+b;

}

}

//测试类

publicclassVariableDemo {

publicstaticvoidmain(String[] args) {

//访问Demo类中的sum方法

/* Demo d = new Demo() ;

d.a = 10 ;

d.b = 20 ;

int result = d.sum();

System.out.println(result);*/

Demod=newDemo() ;

intreuslt=d.sum(10, 20);

System.out.println(reuslt);

}

}

方法重写


packagecom.qf.extends_03;

/**

* 继承关系中,成员方法的访问

* 子类继承父类,如果子类和父类的方法名不一致,分别调用即可! (简单)

*

* 如果子类出现了和父类一模一样的方法,如何访问呢?

* 子类会将父类的功能进行覆盖(复写/重写)--->override:方法重写

*/

classFu{

//父类的成员方法

publicvoidshow(){

System.out.println("show Fu...");

}

}

//子类

classZiextendsFu{

//成员方法

publicvoidmethod(){

System.out.println("method Zi....") ;

}

publicvoidshow(){

super.show(); //既沿用了父亲的功能,还有自己的功能!

System.out.println("show zi...");

}

}

//测试类

publicclassExtendsDemo {

publicstaticvoidmain(String[] args) {

//创建子类对象

Ziz=newZi() ;

z.show() ;

z.method() ;

}

}

利用方法重写对手机举例


packagecom.qf.extends_03;

/**

* 需求:

* 有个一个手机,具备打电话的功能;

*公司后期研发了新手机,这个手机不仅能够打电话,还能看天气预报

*

*

* 子类继承父类,在有的时候,子类想沿用父类的功能,但是使用的自己的功能,

* 子类出现了和父类一模一样的方法,这种叫 "方法重写--override"

*/

//手机

classPhone{

//具备打电话的功能

publicvoidcall(){

System.out.println("手机打电话了...");

}

}

//新手机 ---属于手机

classNewPhoneextends Phone{

//这个手机不仅能够打电话,还能看天气预报

publicvoidcall() {

super.call(); //访问父类的call方法

System.out.println("该手机还可以看天气预报!");

}

}

//测试类

publicclassExtendsDemo2 {

publicstaticvoidmain(String[] args) {

//创建具体的子类

NewPhonenp=newNewPhone() ;

np.call();

}

}

final关键字


packagecom.qf.final_04;

/**

*

* 定义一个父类,子类重写父类的某个成员方法,通过方法重写,最终子类将父类将父类方法覆盖

* 但是有的时候,父类不让子类将自己的某个成员方法进行重写(为了父类的方法的安全性!),Java提供了关键字--->final

*

* final:是一个状态修饰符 (最终的,无法更改的)

*

*

*/

//定义一个父类

classFu{

//成员方法

publicfinalvoidshow(){ //加入final,这个show方法 最终的方法/无法更改的方法

System.out.println("这是一个绝密文件,任何不得更改!");

}

/* public void show(){

System.out.println("这是一个绝密文件,任何不得更改");

}*/

}

//定义一个子类

classZiextends Fu{

/* public void show(){

System.out.println("这一堆垃圾...");

}*/

}

//测试类

publicclassFinalDemo {

publicstaticvoidmain(String[] args) {

//创建子类对象

Ziz=newZi() ;

//调用show方法

z.show() ;

}

}

final关键字的特点


packagecom.qf.final_04;

/**

*final关键字特点:

* 基本概念:最终的/无法更改的

*

* 1)修饰类,该类不能够被继承!(当前这个类是最终类,无法来提供派生类(子类))

* 2)修饰成员方法,该成员方法不能重写(保证父类的方法安全性!)

* 3)修饰变量,此时该变量一个常量,不能在重新赋值!

*

*

*

* 常量:

* 编译时期常量---->基本数据类型:四类八种 (jvm不需要加载)

* public static final int a = 10 ;

* 运行时期常量---->引用数据类型: (jvm进行加载,引用类型 除过String)

* int类型--->包装类 类型 Integer类

* public static final Integer i = new Integer(10) ;

* //i = new Integer(100) ;//报错

*

* 开发中自定义常量:

* public static final 数据类型 变量名 = 初始化值;

*

*/

//定义一个类

//final class Animal{} //动物类

//子类:猫类

//class Cat extends Animal{}

//父类

classFather{

publicstaticfinalintage=20 ; //final修饰成员变量,必须给值,此值不能更改!

publicfinalvoidmethod(){

System.out.println("method Father..");

}

}

//子类

classSonextends Father{

/*public void method(){//不能重写

System.out.println("method Son");

}*/

publicvoidshow(){

finalinta=100 ; //局部变量

//a = 200 ;//数据值不能在更改

System.out.println(a) ;

}

}

//测试类

publicclassFinalDemo2 {

publicstaticvoidmain(String[] args) {

System.out.println(Father.age); //访问父类中静态常量

}

}

final面试题


packagecom.qf.final_04;

/**

* 面试题:

* final修饰基本数据类型和修饰引用数据类型 的区别?

* final修饰的引用数据类型,当前不能在开辟堆内存(不能重新new),里面的成员变量依然可以进行赋值

* final修饰的基本数据类型,基本数据数据值不能在改变!

*/

//定义一个学生类

classStudent{

intage=20;

}

//测试类

publicclassFinalDemo3 {

publicstaticvoidmain(String[] args) {

//创建学生类

//学生对象s没有加入任何修饰符

Students=newStudent() ;

System.out.println(s.age) ;

s.age=30 ;

System.out.println(s.age);

System.out.println("----------------------------") ;

//创建一个新的学生对象

finalStudents2=newStudent() ; //final修饰的引用数据类型,当前不能在开辟堆内存(不能重新new)

System.out.println(s2.age) ;

s2.age=40 ;

System.out.println(s2.age) ;

//s2 = new Student() ;

System.out.println("----------------------------") ;

inta=100 ;

a=200 ;

System.out.println(a) ;

System.out.println("-------------加入final修饰基本类型-------------------") ;

finalintnum=200 ;

//num = 50 ;

}

}

多态


packagecom.qf.duotai_05;

/**

* 什么是多态?

* 从宏观角度去说:一个事物(能看到真实存在的)体现出的不同形态!

* 举例:

* 水--->固态 气态 液态

* 从内存角度去说:一个对象它的所在的类型的变化

* 举例:

* Cat c = new Cat() ; //创建一个只猫 从右边--->左边:猫是猫

* Animal a = new Cat() ; //堆内存是猫 从右边--->左边:猫是动物

*

* 前提条件:

* 1)必须存在继承关系,才能使用多态

* 2)必须存在方法重写,子类继承父类,部分功能将父类进行重写,比如:

* 动物都要吃和睡,具体的动物类:猫/狗/猪,吃和睡的动作不一样

* 3) 必须存在 父类引用指向子类对象 ----->多态的 "向上转型"

* class 父类名{}

* class 子类名 extends 父类名{}

* //多态测试---

* 父类名 对象名 = new 子类名() ;

*

*

*

* 父类名 对象名 = new 子类名() ;

* 多态的成员访问特点:

* 成员变量:编译看左,运行看左!

*

* 成员方法(默认都是非静态): 如果子类重写了父类的方法,编译看左,运行看右!

* 静态方法算不上重写,和静态的都是类成员! (访问方式都是类名来调用的)

*

* 构造方法:继承是多态的前提条件,所以在使用父类引用指向子类对象:Fu fu = new Zi() ;

* 还是要遵循"分层初始化",先让父类构造初始化,然后在是子类构造初始化!

*

*/

//父类

classFu{

//成员变量

intage=40 ;

publicFu(){

System.out.println("Fu的无参构造方法");

}

//成员方法

publicvoidshow(){

System.out.println("show Fu");

}

publicvoidmethod(){

System.out.println("method Fu");

}

publicstaticvoidfunction(){

System.out.println("function Fu");

}

}

//子类

classZiextends Fu{

//成员变量

intage=20 ;

publicvoidshow(){

System.out.println("show Zi");

}

publicZi(){

System.out.println("Zi的无参构造方法");

}

publicvoidplayGame(){

System.out.println("儿子会玩游戏");

}

//静态算不上重写

publicstaticvoidfunction(){

System.out.println("function Zi");

}

}

//测试类

publicclassDuoTaiDemo {

publicstaticvoidmain(String[] args) {

//父类引用指向子类对象 --->格式 父类名 对象名 = new 子类名() ;

Fuf=newZi() ;

//Zi zi = new Zi() ;

//System.out.println(zi.age) ;

System.out.println(f.age) ;

f.show() ;

//f.show2() ; //show2()在Fu类中不存在,编译看左

f.method() ;

//f.function() ;

//Fu.function();

//Zi.function();

//f.playGame() ;编译报错:父类中没有playGame方法

}

}

多态的好处


package com.qf.duotai_05;

/**

* 多态的好处:

* 1)可以提供代码的复用性(由继承保证的)

* 2)可以提高代码的扩展性(健壮性)--->由多态保证

* 父类引用指向子类对象

*/

//动物类

class Animal{

public void eat(){

System.out.println("动物需要吃饭");

}

public void sleep(){

System.out.println("动物困了就需要休息");

}

}

//子类

class Cat extends Animal{

@Override

public void eat() {

System.out.println("猫吃鱼");

}

@Override

public void sleep() {

System.out.println("猫趴着睡");

}

}

//狗类

class Dog extends Animal{

@Override

public void eat() {

System.out.println("狗吃骨头");

}

@Override

public void sleep() {

System.out.println("狗侧着睡");

}

}

//子类

class Pig extends Animal{

@Override

public void eat() {

System.out.println("猪吃白菜");

}

@Override

public void sleep() {

System.out.println("猪躺着睡");

}

}

//优化方案2:定义一个动物工具类

class AnimalTool{

//为了让外界不能new,无参构造方法私有化

private AnimalTool(){}

//定义一个方法: 使用猫的功能

/* public static void useCat(Cat c){//形式参数是猫类型

c.eat();

c.sleep();

}

//定义一个方法:使用狗的功能

public static void useDog(Dog d){//形参参数是狗类型

d.eat();

d.sleep();

}

//定义一个方法:使用猪的功能

public static void usePig(Pig p){

p.eat();

p.sleep();

}*/

public static void useAnimal(Animal a){ //形式参数是引用类型--->父类指向子类对象

// 实际参数:Animal animal = new Cat();

a.eat(); //animal.eat() ;

a.sleep(); //animal.sleep() ;

}

}

//测试类

public class DuoTaiDemo2 {

public static void main(String[] args) {

//使用具体的子类操作

//养了一只狗--创建狗

Dog dog = new Dog() ;

dog.eat();

dog.sleep();

System.out.println("-------------------------------------------------");

//优化:在测试类中提供两个静态方法,方法形式参数传递狗或者猫

//有一只猫对象

Cat cat = new Cat() ; //有名字的对象

useCat(cat) ;

useDog(new Dog());

System.out.println("----------------------优化方案2------------------------------");

//上面代码不好: 随着具体的类越来越多,useXXX(具体的动物类型)方法就会很多,代码量很多!

//定义一个动物工具类 AnimalTool

//AnimalTool at = new AnimalTool();

/* AnimalTool.useCat(new Cat());

AnimalTool.useDog(new Dog());

Pig pig = new Pig() ;

AnimalTool.usePig(pig);*/

//上面代码继续优化:随着具体类型增加,AnimalTool中的静态功能,越来越多

//多态的特点:父类引用指向子类对象:可以提高代码的扩展性

Animal animal = new Cat() ; //堆内存指向的是猫 (猫是的动物)

AnimalTool.useAnimal(animal);

animal = new Dog(); //堆内存是狗 (狗是动物)

AnimalTool.useAnimal(animal);

}

//定义一个方法: 使用猫的功能

public static void useCat(Cat c){//形式参数是猫类型

c.eat();

c.sleep();

}

//定义一个方法:使用狗的功能

public static void useDog(Dog d){//形参参数是狗类型

d.eat();

d.sleep();

}

}

多态的弊端


package com.qf.duotai_06;

/**

* 多态的弊端:

* 不能访问子类的特有功能 父类名 对象名 = new 子类名() ; "向上转型"

*

* 如何解决呢?

* 方案1:

* 直接创建具体的子类对象 子类名 对象名 = new 子类名() ;

* 虽然可以这种方式可以,但是从内存角度考虑:消耗资源,浪费空间,又需要去开辟堆内存!

* 方案2:

* 多态本身:父类引用指向子类对象,能不能将父类的引用转换成子类型?

* "向下转型"---->强转类型转换的格式 ,前提必须有"向上转型"

* 数据类型 变量名 = (目标数据类型)(初始化值或者表达式) ;

*

*

*/

//父类

class Fu{

public void show(){

System.out.println("show Fu");

}

}

//子类

class Zi extends Fu{

public void show(){

System.out.println("show Zi");

}

//特有功能

public void playGame(String gameName){

System.out.println("会玩"+gameName+"游戏");

}

}

//测试类

public class DuoTaiDemo3 {

public static void main(String[] args) {

//父类引用指向子类对象

Fu fu = new Zi() ;

fu.show() ;

//fu.playGame("csgo") ;无法使用playGame方法()父类没有

System.out.println("-----------------------------") ;

//访问子类特有功能

// Zi z = new Zi() ;

//z.playGame("战地5");

System.out.println("------------------------------");

/**

* "向下转型"---->强转类型转换的格式 ,前提必须有"向上转型"

* * 数据类型 变量名 = (目标数据类型)(初始化值或者表达式) ;

*/

Zi z2 = (Zi)fu;

z2.playGame("战地5");

}

}

package com.qf.duotai_06;

/**

* 多态的弊端:不能访问子类特有方法,通过向下转型来访问,这种方式节省内存;

* 但是向下转型使用不当,会出现运行时期的异常

*

*/

//动物类

class Animal{

public void eat(){

System.out.println("eat");

}

}

//猫

class Cat extends Animal{

@Override

public void eat() {

System.out.println("猫吃鱼");

}

}

//狗

class Dog extends Animal{

@Override

public void eat() {

System.out.println("狗吃骨头");

}

}

//测试类

public class DuoTaiDemo4 {

public static void main(String[] args) {

//多态的测试:父类引用指向子类对象

Animal a = new Cat() ;//堆内存是猫 (猫是动物)

//向下转型: 还原猫 (猫是猫)

Cat c = (Cat) a;

a = new Dog () ; //堆内存是狗 (狗是动物)

Dog d = (Dog) a; //还原成狗 (狗是狗)

a = new Cat() ;

//Dog dd = (Dog) a; //ClassCastException:类转换异常

Cat cc = (Cat) a;

}

}

day14


晨写,今日内容


# 晨写

## 1.方法重写和方法重载的区别?

```markdown

方法重写:override

继承体系中,子类继承父类,子类想沿用父类的功能,还是使用自己的功能,出现了和父类一模一样的方法(复写/重写/覆盖),在重写的时候,子类的方法的权限不能更低!

方法重载:overload

在定义的方法是,为了提供功能扩展性,同一个方法名,可以传递不同的参数!

方法名相同,参数列表不同,与返回值无关;

参数列表不同:

1)参数个数

2)参数类型

2)考虑参数顺序

```

## 2.this和super的区别?

```markdown

概念上的区别

this:代表当前类对象的地址值引用

super:代表的父类的空间标识(父类对象的地址值引用)

访问成员变量的区别

this.变量名; 访问的本类中的成员变量

super.变量名; 访问的是父类成员变量

访问构造方法的区别

this(); 访问的是本类的无参构造方法

super() ;访问的父类的无参构造方法

this(xx) ; 访问的是本类的有参构造方法

super(xx) ;访问的是父类的有参构造方法

访问成员方法的区别:

this.方法名() ;访问本类的成员方法

super.方法名() ;访问的是父类的成员方法

```

## 3.final关键字的特点

```markdown

final关键字特点:(状态修饰符,最终的,无法更改的!)

final修饰类,该类不能被继承!

final修饰成员方法,该方法不能被重写

final修饰一个变量,此时变量一个常量;

编译时期常量:基本类型数据类型,jvm不需要加载

运行时期常量:引用数据类型,jvm需要加载

开发中,传统方式自定义常量

public final static 数据类型 变量名 = 初始化值;

```

## 4.什么是多态?多态的前提条件?

```markdown

多态:

一个事物体现的不同形态;(内存中,类型的变化:前提,继承体现中)

多态的前提条件:

1)必须有继承关系

2)存在重写

3)必须父类引用指向子类对象 : "向上转型"

父类名 对象名 = new 子类名() ;

```

## 5.多态的成员访问特点以及多态的好处

```markdown

多态的成员访问特点:

父类名 对象名 = new 子类名() ;

成员变量:编译看左,运行看左!

成员方法:编译看左,运行看右(子类存在方法重写)

静态的方法:编译看左,运行看左! (静态的方法算不上重写,它是跟类相关,随着类的加载而加载!)

构造方法:因为继承关系,先让父类进行构造初始化,然后在是子类初始化,"分层初始化操作"

```

## 6.多态的弊端?如何解决

```markdown

多态的弊端:

Fu fu = new Zi() ; 向上转型

无法子类的特有功能!

解决方案:

1)可以创建Zi zi = new Zi(); 创建子类自己的实例(创建对象)---在重新开辟堆内存空间,消耗资源!

2)推荐: 向下转型 ,前提有向上转型!

Zi z = (Zi)fu; 数据类型 变量名 = (目标数据类型)(表达式或者初始化值) ;

向下转型使用不当:

会出现运行时期异常:ClassCastExeption:类转换异常!

```

----

-----

# 今日内容

## 1.作业

## 2.关于抽象abstract(关键字)--->理解

```

一类事物:看到具体事物,才能里面的行为---->抽取父类的时候不能直接定义 具体类

class 类名{}

--->定义格式:

abstract class 类名{}

概念:

书写格式:

抽象类的本质:

abstract和哪些关键字不能共存!

```

## 3.什么是接口

```

比抽象类更抽象的一种概念!

接口的本质:事物额外的扩展功能!

接口的使用书写格式:

```

## 4.面试题:抽象类和接口的区别?

## 5.关于package 包的真实含义 (理解)

```markdown

开发中:包--->就是目录(文件夹)

代码要进行分层

每一个层:有自己的特殊含义

```

## 6.权限修饰的范围(识记)

```

同一个包/不同包

private

默认修饰符

protected

public

```

## 7.了解 内部类

```

类中类

了解的分类以及构造以及访问方式!

主要jdk原码中,看到懂类的结构!

```

----

---

## 面试题:抽象类和接口的区别?

```markdown

区别:

1)成员的区别

抽象类:

成员变量:既可以常量(定义final修饰的),也可以是变量

成员方法:既可以存在抽象方法,而且也可以存在非抽象方法

如果定义抽象方法,abstract不能省略!

构造方法:存在,无参构造/有参构造方法,让类的数据进行初始化(构造初始化)

接口:

成员变量:只能是常量,存在隐藏的默认修饰符:public static final'

成员方法:只能是抽象方法

构造方法:没有

2)关系区别:

类与类:继承关系,只支持单继承,不支持多继承

类接口:实现关系,一个类继承另一个类的同时,可以实现多个接口

接口与接口:继承关系,可以单继承,也可以多继承以及多层继承

3)设计理念的区别

抽象类:有继承关系,抽象类不能创建对象,借助于抽象类多态(子类是具体类),进行实例化;

体现的核心思想: "is a"的关系

A类是B类的一种或者B类是A列的一种

水果:

橘子

香蕉

接口:体现的是事物的一种额外的扩展功能,本身不具备,需要实现接口才能具备这个功能!

体现的核心思想:

"like a"的关系

猫"跳高" -->

狗"做计算"---> 跳高以及做计算都是额外功能;

```

```markdown

一个类中没有任何抽象方法,将这个类定义为抽象类的意义?

意义:不让创建对象! 肯定会有具体的子类;

```

台灯的问题


packagecom.qf.test_05;

/**

* 设计一个台灯类(Lamp)其中台灯有灯泡类(Buble)这个属性,

* * 还有开灯(on)这个方法

*/

publicclassLamp {

//有一个灯泡类属性

privateBublebuble;

/**

* 开灯的方法

* 请设计出一段代码可以使台灯开启灯泡发亮

*/

/* public void on(RedBuble redBuble){

redBuble.shine() ;

}

public void on(GreenBuble greenBuble){

greenBuble.shine() ;

}*/

//多态:父类引用指向子类对象,on这个方法形式参数传递父类型,

publicvoidon(Bublebuble){//Buble b = new RedBuble() ;

System.out.println("台灯开启...");

buble.shine() ;

}

}

packagecom.qf.test_05;

/**

* 有一个灯泡类

*

* 抽象的灯泡类

*/

publicabstractclassBuble {

//灯泡类有发亮的方法

/* public void shine(){

System.out.println("灯泡会亮");

}*/

//发亮的方法需要被子类进行重写

publicabstract voidshine() ;

}

packagecom.qf.test_05;

/**

* 绿灯泡

*/

publicclassGreenBuble extendsBuble{

@Override

publicvoidshine() {

System.out.println("灯泡可以发绿光了...");

}

}

packagecom.qf.test_05;

/**

* 红灯泡

*/

publicclassRedBuble extends Buble{

@Override

publicvoidshine() {

System.out.println("灯泡可以发红光了");

}

}

packagecom.qf.test_05;

importcom.sun.org.apache.regexp.internal.RE;

/**

* 设计一个台灯类(Lamp)其中台灯有灯泡类(Buble)这个属性,

* 还有开灯(on)这个方法。设计一个灯泡类(Buble),

* 灯泡类有发亮的方法,其中有红灯泡类(RedBuble)和绿灯泡类(GreenBuble)

* 他们都继承灯泡类(Buble)一个发亮的方法,请设计出一段代码可以使台灯开启灯泡发亮

* 红灯泡发红光,绿灯泡发绿光!

*

*

*/

publicclassTest5 {

publicstaticvoidmain(String[] args) {

//创建一个台灯

Lamplamp=newLamp() ;

//多态测试红灯泡

// Buble b = new RedBuble() ;

//lamp.on(b) ;

//匿名对象

lamp.on(newRedBuble());

System.out.println("-----------------------------");

Bubleb=newGreenBuble() ;//抽象类多态

lamp.on(b) ;

System.out.println("----------------------------------");

lamp.on(newGreenBuble()) ;

}

}

抽象


什么是抽象


packagecom.qf.abstract_06;

/**

* 什么是抽象?

* 举例:

* 将猫和狗的共性内容,抽取到了动物(本身就是统称,概括性的)了中,比如:吃和睡的功能,但是在动物了中

* 将吃和睡给出了具体体现,只有看到具体的事物才能知道它具体吃和睡的行为!所以在父类将这些行为,只是给出一个方法声明即可!

* 仅仅给出方法的声明---->含义没有方法体{},抽象功能---->

*

* 有抽象的方法的必须为抽象类

* 抽象类中不一定都是抽象方法!(部分的功能,抽象功能,必须让子类必须重写!)

*

* 抽象方法(成员方法)的格式:

* 权限修饰符 abstract 返回值类型 方法名(空参/带参) ;

*

* 抽象类的本质:

* 强制子类必须将父类的所有的抽象方法,必须实现(重写)

*抽象类的特点:

* 1)不能实例化(不能new 创建对象)

* 2)抽象类的子类一定有具体类,否则无法进行实例化的!

*

*

*

*/

//定义动物类

abstractclassAnimal{

/*public void eat(){

System.out.println("动物都需吃饭");

}*/

//将动物的吃的功能,给出一个声明即可,没有方法体{}

publicabstractvoideat() ;

publicvoidshow(){

System.out.println("show Animal");

}

}

//子类

//abstract class Cat extends Animal{//子类也是一个抽象类,肯定是有个具体的类的,进行父类的实例化!

classCatextends Animal{

@Override

publicvoideat() {

System.out.println("猫吃鱼");

}

}

classDogextends Animal{

@Override

publicvoideat() {

System.out.println("狗吃骨头");

}

}

//测试类

publicclassAbstractDemo {

publicstaticvoidmain(String[] args) {

//创建父类对象

//Animal a = new Animal() ; //不能new ,抽象类

//如何实例化:通过子类(最底层的子类:可以new的)进行实例化

Animala=newCat() ;//父类引用指向子类对象 (抽象类多态!)

a.eat() ;

}

}

抽像类的成员特点


packagecom.qf.abstract_06;

/**

* 抽象类的成员特点:

* 1)成员变量:

* 可以是变量也可以自定义的常量

* 2)成员方法

* 既可以有抽象方法,也可以有非抽象方法!

* 3)构造方法

* 还存在继承关系,分层初始化--->先父类构造初始化,然后是子类构造初始化!

* 无参构造方法/有参构造方法都可以存在,目的都是为了数据进行初始化!

*/

//定义一个父类

abstract classFu{

//定义一个成员变量

publicintnum=20 ;

//自定义常量

publicstaticfinalintnum2=30 ;

//非抽象方法

publicStringshow(){

return"hello,Show Fu!" ;

}

//抽象方法

publicabstract voidfunction() ;

publicFu(){

System.out.println("Fu的无参构造方法");

}

}

//子类

classZiextends Fu{

//重写function

@Override

publicvoidfunction() {

System.out.println("function Zi...");

}

publicZi(){

System.out.println("Zi的无参构造方法");

}

publicZi(Stringstr){

System.out.println("Zi的有参构造方法");

}

}

//测试类

publicclassAbstractDemo2 {

publicstaticvoidmain(String[] args) {

//抽象类多态测试

Fufu=newZi() ; //父类引用指向子类对象

System.out.println(fu.num) ;

System.out.println(Fu.num2) ;

System.out.println("--------------------------------") ;

Stringresult=fu.show() ;

System.out.println(result) ;

fu.function() ;

System.out.println("-----------------------------------");

Fufu2=newZi("hello") ;

}

}

抽象关键字不能和那些关键字共存


package com.qf.abstract_06;

/**

* 抽象abstract关键字不能和哪些关键字共存?

*

* abstract不能和private共用:

* 被private修饰的只能在当前类访问,而abstract修饰的方法,它需要强制子类进行重写;

* abstract不能和static共用:

* abstract修饰的成员方法,需要被子类重写,还是抽象类多态进行实例化Fu fu = new Zi() ;

* 而static随着类的加载而加载(静态方法算不上重写),跟类相关的!

* abstract不能和final共用:

* 被final修饰的成员方法不能被重写,而abstract修饰的成员方法,强转子类重写!

*

*

* abstract:用在类上,标记这个类----抽象类

* 用在方法上,标记这个方法是一个抽象方法!

* 结合public使用居多

*/

//定一个类

abstract class Animal2{

//定义一个抽象方法

//动物都需要吃

public abstract void eat() ;

//private abstract void eat() ;

//public static abstract void show() ;

//public final abstract void show() ;

}

class Cat2 extends Animal2{

@Override

public void eat() {

System.out.println("猫吃鱼") ;

}

}

//测试类

public class AbstractDemo3 {

public static void main(String[] args) {

}

}

抽象类的举例


package com.qf.abstract_07;

/**

* 动物类

*/

public abstract class Animal {//抽象类

private String name ; //动物名称

private int age ; //年龄

private String color ;//颜色

public Animal() {

}

public Animal(String name, int age, String color) {

this.name = name;

this.age = age;

this.color = color;

}

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 String getColor() {

return color;

}

public void setColor(String color) {

this.color = color;

}

//eat和sleep仅仅给出声明

public abstract void eat () ;

public abstract void sleep() ;

}

package com.qf.abstract_07;

/**

* 猫类

*/

public class Cat extends Animal{

public Cat() {

}

public Cat(String name, int age, String color) {

super(name, age, color);

}

@Override

public void eat() {

System.out.println("猫吃鱼");

}

@Override

public void sleep() {

System.out.println("猫趴着睡");

}

//特有功能

public String catchMouse(){

return "猫会抓老鼠" ;

}

}

package com.qf.abstract_07;

/**

*狗类

*/

public class Dog extends Animal{

public Dog() {

}

public Dog(String name, int age, String color) {

super(name, age, color);

}

@Override

public void eat() {

System.out.println("狗吃骨头");

}

@Override

public void sleep() {

System.out.println("狗侧着睡");

}

//特有功能

public void lookDoor(){

System.out.println("狗看门");

}

}

package com.qf.abstract_07;

/**

* 猫狗案例---自己分析属性和行为,加入方法重写,使用多态进行测试

* 猫和狗的共性属性:

* name,age,color

* setXXX(xx)/getXXX

* 猫特有功能:

* 抓老鼠

* 狗特有功能:

* 看门

*

* ---->抽取动物类中--抽象类

* eat()和sleep()---仅仅给出一个声明,此时抽象方法

*

* 使用多态进行测试(抽象类多态)

*/

public class AnimalTest {

public static void main(String[] args) {

//有参构造直接赋值

Animal a = new Dog("藏獒",6,"黑色") ;

System.out.println(a.getName()+"---"+a.getAge()+"---"+a.getColor());

a.eat();

a.sleep();

Dog d = (Dog) a;

d.lookDoor();

//无参构造方法+setXXX(xx)/getxx()展示信息 自己测试

}

}

接口


什么是接口


package com.qf.interface_08;

/**

* 什么是接口?

*

* 举例:

* 猫或者狗本身这个事物不具备"跳高"的功能,经过后天 驯养员的培养,猫和狗就具备了"跳高的功能"

*

* 接口体现的是这个事物本身不具备的功能,是一种额外的扩展功能!

* 只要这个事物实现了接口,它就具备这个功能!

* 如何定义接口

* java定义接口

* interface 接口名{}

*

* 接口的子类(子实现类) implements 接口名{

* 强制子实现类必须将接口中所有抽象方法必须重写!(实现)

* }

*

* 接口的特点:

* 1)接口不能实例化(不能创建对象)

* 2)接口如何实例化?

* 接口多态

* 接口名 对象名 = new 接口的子实现类名() ; (前提:子实现类是非抽象的,就是一个具体类)

*

*

*开发中:

* 接口名和子实现类的命名规范(开发项目中)

* 举例:

* 接口名: interface Inter{}

* 接口的子实现类命名: 接口名 +Impl

* class InterImpl implements Inter{}

*

*

*

*/

//定义一个接口

interface Jump{

//定义一个跳高的功能

/*public void jump(){

System.out.println("可以跳高");

}*/

public abstract void jump() ;

}

//有一个动物类

abstract class Animal{

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

}

//猫类

class Cat extends Animal implements Jump{ //猫 具备跳高的功能,必须实现接口

@Override

public void eat() {

System.out.println("猫吃鱼");

}

//跳高功能

@Override

public void jump() {

System.out.println("猫可以跳高了...") ;

}

}

//测试类

public class InterfaceDemo {

public static void main(String[] args) {

//创建接口Jump对象

// Jump jump = new Jump() ; //接口不能实例化(不能创建对象new)

// 接口名 对象名 = new 接口的子实现类名() ;

Jump jump = new Cat() ;//接口多态

jump.jump();

//jump.eat( );

//向下转型

Cat c = (Cat) jump;

c.eat();

}

}

接口中的成员特点


package com.qf.interface_08;

/**

* 接口中的成员特点:

* 成员变量:只能是常量 存在默认修饰符 public static final

* 成员方法:(非静态):只能是抽象方法,存在默认修饰符 public abstract

* 在接口中是可以定义静态方法,必须有方法体(特例)

* 构造方法: 没有构造方法! 因为子实现类和接口的关系是implements实现关系,

* 只是将接口暴露的额外功能进行实现!

*

*

*/

//定义一个接口

interface Inter{

/*public Inter(){

}*/

// public int num = 10 ;

public static final int num = 10 ;

//public static int num2 = 20 ;

public static final int num2 = 20 ;

/*void show(){//接口只能抽象方法

}*/

public abstract void show() ;

void show3() ;

//静态方法

public static void show2(){

System.out.println("show2()...");

}

}

//接口的子实现类 InterImpl实现Inter接口

class InterImpl implements Inter{

int num = 100 ;

@Override

public void show() {

System.out.println("show InterImpl");

}

@Override

public void show3() {

System.out.println("show3 InterImpl");

}

}

//测试类

public class InterfaceDemo2 {

public static void main(String[] args) {

//接口多态的测试

Inter inter = new InterImpl() ;

System.out.println(inter.num) ;//多态的成员变量的访问

System.out.println(Inter.num);

// inter.num = 200 ;

System.out.println(Inter.num2) ;

//inter.num2 = 300 ; final修饰的变量是一个常量,不能在赋值

Inter.show2();

}

}

接口与接口,类与类,类与接口的关系


package com.qf.interface_08;

/**

* 在Java中,

* 类与类:

* 继承关系,extends,而且只支持单继承,不支持多继承,但是可以多层继承!

* 类与接口

* 实现关系,implements,而且一个类继承另一个类的同时,是可以实现多个接口的!接口名和接口名直接逗号隔开

* class LoverImpl extends Lover implements Love,Study{

* 接口与接口

* 继承关系,extends,不仅支持单继承,也支持多继承,也可以多层继承!

*

*/

//定义一个接口

interface Speak{

public abstract void speakEnglish() ;//会说英语

}

interface Study{

public abstract String study() ;//学习的功能

}

//接口

interface Love extends Study,Speak{

public abstract void love() ;

}

class Lover{

public void show(){

System.out.println("show Lover");

}

}

//实现类

//子实现类 实现接口

class LoverImpl extends Lover implements Love,Study{

@Override

public void love() {

System.out.println("爱生活,爱Java,爱高圆圆!");

}

//实现另一个接口的的功能

@Override

public String study() {

return "学习JavaEE!";

}

@Override

public void speakEnglish() {

System.out.println("会说英语....");

}

}

//测试类

public class InterfaceDemo3 {

public static void main(String[] args) {

//创建具体的子类对象

LoverImpl ll = new LoverImpl() ;

ll.show() ;//父类的方法

ll.love();

ll.study() ;

}

}

day15


水果榨汁实例


packagecom.qf.test_01;

importcom.sun.org.apache.xpath.internal.operations.Or;

/**

* 定义榨汁机JuiceMachine 有榨汁方法makeJuice,传入相应的水果。

* 如果传入的是Apple 输出 "流出苹果汁"

* 传入的是Orange 输出 "流出橙汁"

* 传入的是Banana 输出 "流出香蕉酱"

*/

publicclassTest1 {

publicstaticvoidmain(String[] args) {

/* //创建一个榨汁机

JuiceMachine jm = new JuiceMachine() ;

Fruit f = new Apple() ;

//f = new Orange() ;

// f = new Banana() ;

jm.makeJuice(f) ;

System.out.println("-------------------------------");

jm.makeJuice(new Banana());*/

System.out.println("--------------方式2------------------");

JuiceMachine.makeJuice(newOrange());

}

}

packagecom.qf.test_01;

/**

* 榨汁机

*/

publicclassJuiceMachine {

//构造方法私有化:外界类不能创建对象

privateJuiceMachine(){

}

/**

* 榨汁方法makeJuice,传入相应的水果

*/ //new Apple();

//new Orange();

//new Banana() ;

publicstaticvoidmakeJuice(Fruitfruit){

//传入水果 --形式参数是一个抽象类型,调用该方法,需要传递当前抽象类的子类对象

/**

* 如果传入的是Apple 输出 "流出苹果汁"

* 传入的是Orange 输出 "流出橙汁"

* 传入的是Banana 输出 "流出香蕉酱"

*/

//变量名 instanceof 数据类型:判断前面变量名是否为这个后面这个类型的实例

if(fruitinstanceofApple){

//fruit是Apple的实例

fruit.juice() ;

}elseif(fruitinstanceofOrange){

//fruit是Orange类的实例

fruit.juice() ;

}else{

fruit.juice(); //流出香蕉酱

}

}

}

packagecom.qf.test_01;

/**

* 水果类

*/

publicabstractclassFruit {

//只有看到具体的水果---才能流出对应的水果汁,仅仅给出一个方法声明

publicabstractvoidjuice() ;

}

packagecom.qf.test_01;

/**

* 橙子

*/

publicclassOrange extendsFruit{

@Override

publicvoidjuice() {

System.out.println("流出橙汁!");

}

}

packagecom.qf.test_01;

/**

* 香蕉类

*/

publicclassBanana extendsFruit{

@Override

publicvoidjuice() {

System.out.println("流出香蕉酱!");

}

}

packagecom.qf.test_01;

/**

* 苹果类

*/

publicclassApple extendsFruit{

@Override

publicvoidjuice() {

System.out.println("流出苹果汁");

}

}

宠物商店实例


packagecom.qf.test_02;

/**

* 定义一个动物类,里面有一个方法voice(),

* 定义一个类Cat,实现voice方法

* 然后增加一种新的动物类型:Pig(猪),实现voice()方法。

* 定义一个Dog类,实现voice方法

* 定义一个Store(宠物店)类的getInstance方法:

* 如果传入的参数是字符串dog,则返回一个Dog对象;

* 如果传入pig,则返回一个Pig对象;否则,返回一个Cat对象。

*

* 提示:字符串进行判断 通过equals(字符串)方法

*/

publicclassTest2 {

publicstaticvoidmain(String[] args) {

//创建一个宠物店

/*Store store = new Store() ;

Animal animal = store.getIntance("dog");//方法本质就是 创建一只狗 new Dog() ;

animal.voice() ;

animal = store.getIntance("cat") ;

animal.voice();

animal = store.getIntance("pig") ;

animal.voice();*/

Animalan=Store.getIntance("monkey");

an.voice();

}

}

packagecom.qf.test_02;

/**

* 宠物店

*/

publicclassStore {

//构造方法私有化:外界不能new

privateStore(){}

/**

* 提供getInstance方法:

* 如果传入的参数是字符串dog,则返回一个Dog对象;

* 如果传入pig,则返回一个Pig对象;否则,返回一个Cat对象。

*/

//利用多态:提高代码扩展性!

//方法的返回值是一个类:抽象类--->需要返回该抽象类的子类对象

publicstaticAnimal getIntance(Stringtype){

//字符串进行比较:必须使用

// 当前字符串.equals(另一个字符串):比较两个字符串的内容是否相同

// 相同,true;否则false---

//String类:字符串:进行equals的时候,将常量放前面,否则可能出现空指针异常

if("dog".equals(type)){

returnnewDog() ;

}elseif("pig".equals(type)){

return newPig() ;

}else{

return newCat() ;

}

}

//创建Stroe对象 Stroe s = new Store() ;

// Animal a = s.getInstance("dog") ; //Animal a = new Dog();

}

package com.qf.test_02;

/**

* 动物类

*/

public abstract class Animal {

//面有一个方法voice():每一个具体动物才有具体的行为---抽象

public abstract void voice() ;

}

package com.qf.test_02;

/**

* 猫

*/

public class Cat extends Animal{

@Override

public void voice() {

System.out.println("猫发出喵喵喵的声音");

}

}

package com.qf.test_02;

/**

*狗类

*/

public class Dog extends Animal{

@Override

public void voice() {

System.out.println("狗发出汪汪汪叫的声音");

}

}

package com.qf.test_02;

/**

* 猪类

*/

public class Pig extends Animal{

@Override

public void voice() {

System.out.println("猪发出哼哼叫的声音");

}

}

方法的形式参数问题: 只研究引用类型


package com.qf.args_01;

/**

* 方法的形式参数问题: 只研究引用类型

*

* 方法形式参数:

* 具体类:调用该方法,此时实际参数需要的是当当前类的对象!

* 抽象类

* 接口

*

*/

class Student{

public void studyJavaEE(){

System.out.println("正在学习JavaEE之JavaSE") ;

}

}

//定义一个StudentDemo类

class StudentDemo{

public void show(Student s){//方法的形式参数是一个学生类型

s.studyJavaEE() ;

}

}

//测试类

public class ArgsDemo1 {

public static void main(String[] args) {

//访问StudentDemo类中的show方法

StudentDemo sd = new StudentDemo() ;

Student student = new Student() ;

sd.show(student) ;

System.out.println("---------------------------------------") ;

//另一种方式:匿名对象

new StudentDemo().show(new Student());

}

}

package com.qf.args_01;

/**

* 方法的形式参数问题: 只研究引用类型

*

* 方法形式参数:

* 具体类:调用该方法,此时实际参数需要的是当当前类的对象!

* 抽象类:调用该方法,此时实际参数需要的是当前抽象类的子类对象!

* 接口

*

*/

//定义一个Person类

abstract class Person{

/*public void work(){

System.out.println("人都需要工作");

}*/

public abstract void work() ;

}

//定义一个PersonDemo类

class PersonDemo{

public void function(Person p){//方法的形式参数是引用类型--抽象类,抽象类不能new,需要传递抽象类的子类对象!

p.work() ;

}

}

//定义抽象类的子类(具体类)

class Worker extends Person{

@Override

public void work() {

System.out.println("爱工作,爱Java,爱高圆圆!");

}

}

//测试类

public class ArgsDemo2 {

public static void main(String[] args) {

//访问PersonDemo类中的function方法?

PersonDemo pd = new PersonDemo() ;

//Person p = new Person() ;抽象类不能实例化(不能创建对象)

Person person = new Worker() ;

pd.function(person) ;

System.out.println("----------------------------------") ;

new PersonDemo().function(new Worker());

}

}

package com.qf.args_01;

/**

* 方法的形式参数问题: 只研究引用类型

*

* 方法形式参数:

* 具体类:调用该方法,此时实际参数需要的是当当前类的对象!

* 抽象类:调用该方法,此时实际参数需要的是当前抽象类的子类对象!

* 接口类型:调用该方法,此时实际参数需要的是接口的子实现类对象!

*

* 开发中:方法形式参数是具体类以及接口情况居多的!

*/

//定义一个接口

interface Love{

public abstract void love() ;

}

//定义一个类:LoveDemo

class LoveDemo{

public void method(Love love) {//方法的形式参数是一个接口? 接口不能new,需要接口的子实现类对象

love.love();

}

}

//需要有定义接口的子实现类,实现Love接口

class LoveImpl implements Love{

@Override

public void love() {

System.out.println("love Java!");

}

}

//测试类

public class ArgsDemo3 {

public static void main(String[] args) {

//要访问LoveDemo类中的method方法?

LoveDemo ld = new LoveDemo() ;

// Love l = new Love() ;//接口不能实例化

// ld.method(l);

//接口多态:接口名指向子实现类

Love l = new LoveImpl() ;

ld.method(l);

System.out.println("--------------------------");

new LoveDemo().method(new LoveImpl()) ;

}

}

权限修饰符的范围


package com.qf.permission_03;

/**

* 权限修饰符的范围

*

* 同一个包下的同一个类中 同一个包下的子类中/同一个包下的无关类中 不同包下的子类中 不同包下的无关类中

* private:私有 Y

* 默认修饰符 Y Y

* protected:受保护的 Y Y Y

* public:公共的/公开的 Y Y Y Y

*

*

*/

public class PermissionDemo {

public static void main(String[] args) {

PermissionDemo pd = new PermissionDemo() ;

pd.show() ;

pd.show2() ;

pd.show3() ;

pd.show4();

}

//私有

private void show(){

System.out.println("show PermissionDemo");

}

//默认修饰符

void show2(){

System.out.println("show2 PermissionDemo");

}

//受保护的

protected void show3(){

System.out.println("show3 PermissionDemo");

}

//公共的

public void show4(){

System.out.println("show4 PermissionDemo");

}

}

package com.qf.permission_03;

/**

* PeermissionDemo的子类

*/

public class PermissionDemo2 extends PermissionDemo{

public static void main(String[] args) {

//创建子类对象

PermissionDemo2 pd2 = new PermissionDemo2() ;

// pd2.show() ; 私有用不了

pd2.show2() ; //默认修饰符

pd2.show3() ; //受保护的

pd2.show4() ;//公共的

}

}

package com.qf.permission_03;

/**

* 同一个包下的无关类中

*/

public class PermissionTest {

public static void main(String[] args) {

//创建PermissionDemo类对象

PermissionDemo pd = new PermissionDemo() ;

pd.show2() ;//默认修饰符

pd.show3(); //受保护的

pd.show4(); //公共开的

}

}

-----------------------------另一种写法


package com.qf.permission_04;

import com.qf.permission_03.PermissionDemo;

/**

* 不同包下的子类中

*/

public class PermissionDemo3 extends PermissionDemo {

public static void main(String[] args) {

//创建PermissionDemo3类对象

PermissionDemo3 pd3 = new PermissionDemo3() ;

// pd3.show2() ; //默认修饰符用不了

pd3.show3(); //受保护的

pd3.show4();

}

}

package com.qf.permission_04;

import com.qf.permission_03.PermissionDemo;

/**

* 不同包下的无关类中

*/

public class PermissionTest2 {

public static void main(String[] args) {

//创建PermissionDemo类对象

PermissionDemo pd = new PermissionDemo() ;

// pd.show() ;//私有的

//pd.show2();//默认修饰符

//pd.show3() ;//受保护的

pd.show4() ;

}

}

方法的返回值问题


package com.qf.return_02;

/**

* 方法的返回值问题:

* 要么基本类型/引用数据类型

* 基本类型:简单,要什么类型,使用指定的类型接收即可!

*

*

* 研究的方法的返回值引用类型:

* 方法的返回值如果是引用类型:

* 具体类:需要返回该具体类的对象!

* 抽象类:

* 接口:

*/

class Demo{

//对两个数据求和

public int sum(int a,int b){

return a+ b;

}

}

//定义学生类

class Student{

public void study(){

System.out.println("好好学习,天天向上!");

}

}

//StudentDemo类

class StudentDemo{

public Student show(){

//?补全代码

//return Student ; 错误

//方式1:

// Student s = new Student() ;

//return s ;

//方式2:匿名对象

return new Student() ;

}

}

//测试类

public class ReturnDemo1 {

public static void main(String[] args) {

Demo d = new Demo() ;

int result = d.sum(10, 15);

System.out.println(result);

System.out.println("-------------------------");

//访问StudentDemo类中的方法

StudentDemo sd = new StudentDemo() ;

Student student = sd.show(); //show方法就是new Student()

student.study();

}

}

研究的方法的返回值引用类型:


package com.qf.return_02;

/**

* 研究的方法的返回值引用类型:

* 方法的返回值如果是引用类型:

* 具体类:需要返回该具体类的对象!

* 抽象类:需要返回该抽象类的子类对象!

* 接口:

*/

//定义一个Person类

abstract class Person{

public abstract void work() ;

}

//PersonDemo类

class PersonDemo{

public Person function(){//方法的返回值是一个抽象类

//?

// return new Person() ; 抽象类不能实例化

//方式1:抽象类多态

//Person p = new Programmer() ;

//return p;

//方式2:直接匿名对象 (创建子类对象)

return new Programmer() ;

}

}

//定义一个类,继承Person

//程序员

class Programmer extends Person{

@Override

public void work() {

System.out.println("程序员日日夜夜敲代码!");

}

}

//测试类

public class ReturnDemo2 {

public static void main(String[] args) {

//访问PersonDemo类的function方法

PersonDemo pd = new PersonDemo() ;

Person person = pd.function(); //funciton方法 本质--->创建了子类对象

person.work();

}

}

package com.qf.return_02;

import sun.util.resources.ms.CalendarData_ms_MY;

/**

* 研究的方法的返回值引用类型:

* 方法的返回值如果是引用类型:

* 具体类:需要返回该具体类的对象!

* 抽象类:需要返回该抽象类的子类对象!

* 接口:需要返回接口子实现类对象!

*/

//定义一个接口

interface Mary{ //结婚的接口

public abstract void mary() ;

}

//定义一个MaryDemo

class MaryDemo{

public Mary method(){

//?

//return new Mary() ;//接口不能new

//方式1:

//Mary mary = new MaryImpl() ;

// return mary ;

//方式2:

return new MaryImpl() ;

}

}

//需要定义接口的子实现类

class MaryImpl implements Mary{

@Override

public void mary() {

System.out.println("要结婚了,很开心...");

}

}

//测试类

public class ReturnDemo3 {

public static void main(String[] args) {

//需求:访问MaryDemo类中的method方法?

MaryDemo md = new MaryDemo() ;

Mary mary = md.method();

mary.mary();

System.out.println("--------------------------");

Mary mary2 = new MaryDemo().method();

mary2.mary();

}

}

day16


回顾&今日内容


#回顾

##形式参数问题

```markdown

研究的引用数据类型:数组,类,接口

publicvoidshow(int[] arr){} //如果数组,需要有一个数组对象

publicviodshow(具体类型变量名){//调用方法,实际参数需要创建当前这个类的对象

使用这个变量名

}

publicvoidshow(抽象类型变量名){//调用方法,实际参数需要传递当前抽象类的子类对象

///

}

publicvoidshow(接口类型变量名){//调用方法,实际参数需要传递的是当前接口的子实现类对象!

//

}

```

##返回值问题

```markdown

研究的时候引用类型:数组,类,接口

publicint[] method(int[] arr) { //返回是数组类型,需要返回数组对象

//完成了各种排序

return数组对象;

}

public具体类 method(){//返回值是具体类型,需要返回的是当前具体类的对象!

//?

//1)创建具体类对象

//return 对象名;

//2)直接使用匿名对象

returnnew类名() ;

}

public抽象类method(){//返回值是抽象类型,需要返回的是该抽象类的子类对象!

//抽象不能实例化

抽象类对象名=new子类名() ; //抽象类多态

return对象名;

//return new 子类名() ;

}

public接口method(){//返回值是接口类型,需要返回的是当前接口的子实现类对象!

//接口不能实例化

//接口多态

接口名对象名=new子实现类名() ;

return对象名 ;

//return new 接口子实现类名();

}

```

##包的含义(了解)

```

package:在真实开发中,代码需要分层,借助包名

公司域名反写.pojo:存储的实体类 举例:商品类/用户类/订单类/购物车/医生等等

Order订单类

.service:存储业务接口层 OrderService

.service.impl:业务接口实现层 OrderServiceImpl:订单业务接口实现

.dao: 存储数据访问接口(DataAccessObject:数据访问对象) OrderDao

.dao.impl: 数据访问接口实现---->访问数据库:获取数据库

.utils :存储的工具代码(自定义的工具,jdk提供/第三方提供的)

.test :测试代码-----单元测试 junit.jar包

```

##权限修饰符的范围

| |在同一个包下的同一个类中|在同一个包下的子类中/同一个包下的无关类中|在不同包下的子类中|不同包下的无关类中|

|-----------------|------------------------|-----------------------------------------|------------------|------------------|

|private私有 |Y | | | |

|默认修饰符 |Y |Y | | |

|protected受保护的|Y |Y |Y | |

|public公共的 |Y |Y |Y |Y |

----

----

----

#今日内容

##1.内部类(了解的格式)

```

分类有哪些

成员内部类

局部内部类

内部类的一些注意事项

```

##2.内部类的一种简写:针对接口/抽象类:匿名内部类(重点)

##3.数组高级排序---选择排序

##4.预习Object/String类重点功能

```

常用类

Object -->hashCode()/equals():引用类型比较

StringtoString():默认就是对象名地址值(没有意义)

clone():克隆

String 重点类(使用最多)

StringBuffer 重点

Integer 重点

Character

Random:伪随机数生成器

BigDecimal:针对小数进行精确计算

Math

Scanner:提供类判断功能

System:

java.util.Date:日期 重点类

```

内部类


什么是内部类


packagecom.qf.innerclass_01;

/**

* 什么是内部类?

* 在Java中,在一个类中定义另一个类:

* 举例

* 在类A中,定义一个类B,将类B称为类A的内部类,类A是类B的外部类!

*

* 分类:

* 成员内部类:在类中,方法外定义的类

* 局部内部类:在方法定义中定义的类

*/

classOuter{

//成员内部类

/*class Inner{

public void show(){

System.out.println("show Inner");

}

}*/

//Outer的成员方法

publicvoidmethod(){

//局部内部类

classInner{

publicvoidshow(){

System.out.println("show Inner");

}

}

System.out.println("method Outer");

}

}

//测试类

publicclassInnerClassDemo {

}

成员内部类


packagecom.qf.innerclass_01;

/**

*成员内部类:

* 在外部类中,在外部类的成员方法外

*

* 特点:

* 可以访问外部类的成员包括私有!

*

*

* 直接去访问外部类的中的成员内部类的成员方法:特有方式 (成员内部类没有private以及static修饰!)

* 外部类.内部类名 对象名 = new 外部类名().new 内部类名() ;

*/

//外部类

classOuter2{

//成员变量

public intnum=20 ;

private intnum2=50 ;

//成员内部类

classInner2{

//成员方法

publicvoidshow(){

System.out.println(num) ;

System.out.println(num2) ;

}

}

//外部类的成员方法

publicvoidmethod(){

// show() ; Outer2自己的show方法

//访问成员内部类的成员方法

//创建Inner2类对象

Inner2in=newInner2() ;

in.show() ;

}

}

//测试类

publicclassInnerClassDemo2 {

publicstaticvoidmain(String[] args) {

//创建外部类对象

//访问外部类的成员方法,间接的调用了成员内部类的成员方法

Outer2ou=newOuter2() ;

ou.method() ;

System.out.println("--------------------------------------------------") ;

//测试类中:想直接去访问外部类里面的成员内部类的show

//外部类.内部类名 对象名 = new 外部类名().new 内部类名() ;

Outer2.Inner2oi=newOuter2().newInner2() ;

oi.show() ;

}

}

成员变量所涉及的修饰符的问题


packagecom.qf.innerclass_01;

/**

* 成员内部类所涉及到的修饰符的问题:

* 有的时候不想让外部类直接去访问内部类的成员,为了保证内部类的成员安全,加入private

* 举例:

* 人有身体,身体有心脏;

* 伪代码

* class Body{

* //身体内有心脏

* //为了保证安全性,加入private修饰

* private class Heart{

* //成员方法

* public void operator(){

* System.out.println("心脏搭桥") ;

* }

* }

*

* //外部类的成员方法

* public void method(){

* if(你是外科医生){

* //创建Heart对象,去调用operator方法

* }

* }

*

*

* }

*

*

* //直接访问成员内部类中的operator方法

* 外部类名.内部类名 对象名 = new 外部类名().new 内部类名() ;

* Body.Heart bh = new Body().new Heart() ;会报错的

*

*

* 成员内部类可以使用过static修饰:

* 特点:静态的成员内部类它里面的所有 成员方法:

* 无论是静态的方法还是非静态的,访问外部类的成员:必须先为静态

*

* 想直接去访问静态的成员内部类的这些成员方法:??

*

* 外部类名.内部类名 对象名 = new 外部类名.内部类名();

*

*/

//外部类

classOuter3{

privateintnum=100;

publicstaticintnum2=20 ;

//静态修饰

staticclassInner3{ //Inner3现在看成是外部类的静态成员!

//非静态的方法

publicvoidshow(){

// System.out.println(num) ;

System.out.println(num2) ;

System.out.println("show Inner3");

}

//静态的方法

publicstaticvoidshow2(){

System.out.println(num2) ;

//System.out.println(num) ;

System.out.println("show2 Inner3");

}

}

}

//测试类

publicclassInnerClassDemo3 {

publicstaticvoidmain(String[] args) {

//访问成员内部类的成员方法

//外部类名.内部类名 对象名 = new 外部类().new 内部类名() ;

//Outer3.Inner3 oi = new Outer3().new Inner3() ; 用不了,只能针对非静态的成员内部类!

//针对静态的成员内部类:直接去访问里面的成员方法

//外部类名.内部类名 对象名 = new 外部类名.内部类名();

Outer3.Inner3oi=newOuter3.Inner3() ;//Inner3类看成是Outer3的静态成员

oi.show() ;

oi.show2() ;

System.out.println("----------------------------------------");

//show2()是静态的成员内部类的静态成员

Outer3.Inner3.show2();

}

}

局部内部类


packagecom.qf.innerclass_02;

/**

* 局部内部类:

* 在外部类的成员方法中定义的类

* 特点:

* 局部内部类也是可以直接访问外部类的成员变量,包括私有!

*

* 面试题:

* 局部内部类里面的成员在访问局部变量的时候,局部变量有什么要求?

*

* JDK8以前的版本,局部内部类在访问外部类的成员方法中的局部变量的时候,此时局部变量必须加入final修饰!

* 原因:

* 局部变量的生命周期随着方法调用而存在,随着方法调用结束而消失;

* 外部类的成员方法调用完毕,此时这个局部变量应该释放了,但是当前这个成员方法中创建局部内部类对象

* 使用局部内部类对象访问它里面的成员方法,成员方法还在使用这个局部变量,所以此时这个变量为常量,显示的加入

* final修饰

* JDK8以及jdk8以后:优化了

* 可以通过反编译工具---->自动加入final,还是定义一个常量

*/

//外部类

classOuter{

privateintnum=20 ;

//外部类的成员方法

publicvoidmethod(){

intx=200 ;

//局部内部类

classInner{

//成员方法

publicvoidshow(){

System.out.println("show Inner") ;

System.out.println(num);

System.out.println(x) ;

}

}

//创建Inner

Innerinner=newInner() ;

inner.show();

}

}

//测试类

publicclassInnerClassDemo {

publicstaticvoidmain(String[] args) {

//创建外部类对象

Outerouter=newOuter() ;

outer.method();

}

}

内部类的面试问题


packagecom.qf.innerclass_02;

/**

* 面试题

* 在控制台分别打印

* 30

* 20

* 10

*

* 内部类外部类没有继承关系,不能使用super!

*/

classOuter2{

intnum=10 ;

//成员内部类

classInner2{

intnum=20 ;

publicvoidshow(){

intnum=30 ;

//补全代码

System.out.println(num) ; //就近原则

System.out.println(this.num) ; //访问本类的成员变量

// System.out.println(new Outer2().num) ; //创建外部类对象.变量名

//this:代表当前类---->Outer2.this--->外部类的this限定(访问的是外部类中的信息)

System.out.println(Outer2.this.num);

}

}

}

//测试类

publicclassInnerClassDemo2 {

publicstaticvoidmain(String[] args) {

Outer2.Inner2oi=newOuter2().newInner2() ;

oi.show();

}

}

匿名内部类


packagecom.qf.innerclass_02;

/**

* 面试题

* 在控制台分别打印

* 30

* 20

* 10

*

* 内部类外部类没有继承关系,不能使用super!

*/

classOuter2{

intnum=10 ;

//成员内部类

classInner2{

intnum=20 ;

publicvoidshow(){

intnum=30 ;

//补全代码

System.out.println(num) ; //就近原则

System.out.println(this.num) ; //访问本类的成员变量

// System.out.println(new Outer2().num) ; //创建外部类对象.变量名

//this:代表当前类---->Outer2.this--->外部类的this限定(访问的是外部类中的信息)

System.out.println(Outer2.this.num);

}

}

}

//测试类

publicclassInnerClassDemo2 {

publicstaticvoidmain(String[] args) {

Outer2.Inner2oi=newOuter2().newInner2() ;

oi.show();

}

}

匿名内部类开发中使用场景2:方法返回值是抽象类或者接口


packagecom.qf.return_05;

/**

* 匿名内部类开发中使用场景2:

* 方法返回值是抽象类或者接口

*/

interfaceLove{

voidlove() ;

}

//LoveDemo

classLoveDemo{

publicLovemethod(){ //返回是一个接口:返回接口的子实现类对象

//?如何返回

//接口不能new

//接口多态

//Love l = new LoveImpl() ;

//return l;

//return new LoveImpl() ;

//2使用接口的匿名内部类

/**

* new 类名或者接口(){

* //重写方法

* }

*/

return newLove() {

@Override

publicvoidlove() {

System.out.println("爱生活,爱Java,爱高圆圆!");

}

};

}

}

//定义一个子实现类

classLoveImplimplements Love{

@Override

publicvoidlove() {

System.out.println("love life,love 高圆圆");

}

}

//测试类

publicclassReturnDemo {

publicstaticvoidmain(String[] args) {

LoveDemold =newLoveDemo() ;

Lovelove=ld.method(); //使用的接口匿名内部类的子实现类对象!

love.love();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值