黑马程序员————引用型变量的形式参数和返回值,权限修饰符,内部类

时间:2021-11-20 12:06:55


------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------


一.形式参数和返回值
 形式参数:基本数据类型和引用数据类型
引用数据类型的形参:
 A.类:    实参必须是此类对象的引用,或者是null(如果是null的话,传入方法中的话,可以编译通过,但是一旦调用,就会出现空指针异常,所以在方法中使用前可以先  加  上 一步判断。)
 B.抽象类:实参必须是此抽象类的子类的对象的引用。或者是null(同样最好也是要判断一下不然也是空指针异常)
 C.接口:  实参必须是此接口的子类的对象的引用。或者是null(同样最好也是要判断一下不然也是空指针异常)

1》具体类作为形式参数:




class Student {

public void show() {

System.out.println(“student--->>show”);

}

}



class StudentDemo {



public void method(Student s) {

//如果参数是一个类名,那么实际需要的是一个具体的对象的引用

s.show();

}

}



class StudentTest {

public static void main(String[] args) {

//如何调用StudentDemo中的method方法呢?

StudentDemo sd = new StudentDemo();//此处采用多态的写法更好啊

Student s = new Student();

sd.method(s);

//当然此处可以使用一个匿名类来代替实例化对象new StudentDemo().method(new Student());

}

}




2》抽象类作为形式参数:
123
abstract class Person {    public abstract void show();} class PersonDemo {    public void method(Person p) {        p.show();    }} //自己定义类继承自Person类//Person类是抽象类,不能够实例化,所以必须定义一个子类,重写其方法,且还可以实例化子类,将子类的对象赋值给父类的引用。class  Student entends Penson{    public void show(){     System.out.println("输入子类中show");    }} class PersonTest {    public static void main(String[] args) {        //如何调用PersonDemo中的method方法呢?        PersonDemo pd = new PersonDemo ();//这两行代码可以互换顺序,因为彼此没有影响。        Person p = new Student();                     //多态的写法了,对于抽象类更是必须如此了.实际上不是多态的写法也是可以的Student s=new Student();一样可以的        pd.method(p);                       //还可以写成newPersonDemo().method(new Student());    } }



3》》》接口作为形式参数,类似抽象类作为形式参数。


 返回值:基本数据类型和引用类型

 引用数据类型的返回值:
 A.类:    返回的,必须是此类对象的引用,或者是null;

 B.抽象类:返回的,必须是这个抽象类的子类的对象的引用,或者是null
 C.接口:  返回的,必须是此接口的子类对象的引用,或者是null.
 return后面的值可以是返回值类类型的引用或者是子类对象的引用(抽象类和接口的时候)用来接收的必须是返回值类型的类的引用或者是其父类的(当其继承自一个父类的时候)一个引用才可以。 用来接收的还可以是其子类的引用,但是前提是要确定该子类就是方法中的那个子类,需要用instanceof判断。 且在赋值时要使用强制类型转换。同样返回值在使用的时候做好也是判断一下。if(返回的应用==null){}因为如果返回的是一个null,执行调用方法的时候就会空指针异常。
 1》》》具体类作为返回值类型:


class Student {

public void show() {

System.out.println(“show”);

}

}



class StudentDemo {

public Student getStudent() {

//Student s = new Student();

//return s;

return new Student();

}

}



class StudentTest {

public static void main(String[] args) {

//如何测试呢?

//原本我可以直接通过Student创建对象,调用功能

//但是现在不让这样做,怎么办呢?

StudentDemo sd = new StudentDemo();

Student s = sd.getStudent();

s.show();

}

}


 2》》》抽象类作为返回值类型:

abstract class Person {

public abstract void show();

}



class PersonDemo {

public Person getPerson() {

Person p = new ???();//Student

return p;



//return new ???();///Student,其实两种方法谁都可以

}

}



//自己定义类继承自Person类,否则PersonDemo代码无法完成?

//自己定义Person的子类就可以

class Student extends Person{

public void show(){

}

}





class PersonTest {

public static void main(String[] args) {

//如何调用PersonDemo中的method方法呢?

PersonDemo pd = new PersonDemo ();

Person p = pd.getPerson(); //接收的必须就是 Person类或者是其父类,但是这里Person没父类

p.show(); //其实调用的是Student的

}



}



3》》》接口作为返回值类型,类似抽象类作为返回值

 链式编程法

 new Person().setPerson().show();其可以解释为,new Person()创建一个对象,并且调用了一个类中的方法setPerson()但是该方法返回了一个类类型的引用再次调用了一个方法。



二.访问权限修饰符:
          1.四种:public、protected、(默认)、private
           2.修饰类:public 和 (默认)。
                    public修饰类,同一个项目下的类都可以访问,可以跨包访问。
                    默认权限只能同包下访问。
  
           修饰成员:四种都可以;
                1.public :公有,整个项目的所有类都可以访问;
                2.protected:受保护的。包内的其它类可以访问。其它包,只有子类可以访问;
                3.(默认):包内的其它类可以访问;
                4.private:私有:只能在类的内部访问;

         3.类及其成员访问修饰符汇总
                1.类:(默认):说明这个类,只能被同包下的其它类访问;
                        public:说明这个类,可以被同项目任何包下的任何类访问;
                        final: 说明此类是个最终类,不能被继承了;
                        abstract:此类是个抽象类,不能被实例化,只能被继承;
                        常用访问修饰符:public
                2.成员变量:
                           1.4种访问修饰符:
                           2.final:常量;
                           3.static:静态的;
                           常用访问修饰符:private
                3.成员方法:
                        1.四种访问修饰符;
                        2.final:不能被重写
                        3.static:静态方法;
                        4.abstract:抽象方法;

                        常用的访问修饰符:public
                4.构造方法:
                         1.四种访问修饰符;
            常用的访问修饰符:pub


三.内部类:把类定义在其他类的内部,这个类就被称为内部类

         1、内部类的访问特点:
                   内部类,跟其他成员一样,就是属于外部类的一个成员;此内部类可以访问其它的成员
                   内部类可以直接访问外部类的成员,包括私有。
                  外部类要访问内部类的成员,必须创建对象      
          2、内部类中可以定义什么:
                 1).成员变量
                 2).成员方法;
                 3).构造方法:有构造方法,就可以创建对象。
                 4).代码块;构造代码块可以有
                 5).类,内部类中还可以定义类
          3、根据定义的位置不同,内部类可以分为:成员内部类和局部内部类。
                   成员内部类:和类的成员一样,也是,顺序访问的。
                   局部内部类:定义在方法内或者是局部的代码中的类。
 
            4、成员内部类:
                   A、在外界实例化成员内部类:
                          1)首先实例化外部类
                          2)再去实例化其成员内部类
                          如果B是A的内部类,那么实例化B:  A a=new A();A.B b=a.newB();也可以直接一个语句A.B b=new A().B();
                   B、访问修饰问题
                        1)四中访问权限修饰符
                         2)private,表示只能在外部类的范围内使用,保证数据的安全性
                         3)static为了让数据访问更方便。实例化一个静态的成员内部类,可以不用外部类的对象,直接用类名就可以:A.C c = new A.C();
                                 被静态修饰的成员内部类只能访问外部类的静态成员。非静态的成员内部类,成员只能是非静态的。
                                 内部类被静态修饰后的方法有静态和非静态之分。他们的访问和不用静态是不一样的。

                                  访问非静态方法:外部类名.内部类名 对象名 = new 外部类名().内部类名();对象名.方法名();
                                  访问静态方法:  上面创建的对象访问,或者外部类名.内部类名.方法名();
 
                 C.成员内部类成员变量访问问题:
                       1).同其它成员一样,可以访问外部类中的其它成员;即使是私有的;
                        2).实例化一个"成员内部类"的对象:
A.B b = new A().new B();
                        3).成员变量的覆盖:



class A{

int num = 10;

class B{

int num = 20;

void show(){

int num = 30;

System.out.println(num);//30 局部变量

System.out.println(this.num);//20 B类成员变量

System.out.println(A.this.num);//10 A类成员变量

}

}

}


          5.局部内部类:
                1).定义在某个方法或其它局部代码内的内部类;
                     只有局部代码得到执行时才会加载。
                 2).无法在方法的外部直接实例化局部内部类,但是在方法内是可以的。
                         在方法外,可以获取局部内部类的对象,但此局部内部类,要实现一个外部定义的接口或继承一个父类;
Java code?

interface IA

{

void fun();

}

class A

{

//public B show(){//不能返回B类型,因为执行show方法的时候,还没有B类型呢。



public IA show(){



final int num = 10;



class B implements IA

{

public void fun(){

System.out.println("B--fun num = " + num);

}

}

return new B();





}

}

                   

 3).注意:局部内部类可以访问局部变量,但是要求这个局部变量必须被声明为:final的(常量)
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量。
为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值

 


 class A{

int num = 10;

void show(){

final int num = 20;//

class B{

void f(){

System.out.println("num = " + num);

}

}

}

}


          6.匿名内部类:
                1).定义在局部;
                 2).跟局部内部类一样,只是可以省略名字:
Java code?



interface IA

{

void fun();

}

class A

{

public IA show(){





//定义了一个有名字的内部类;

/* class B implements IA

{

public void fun(){

System.out.println("B-->fun()");

}

}

IA a = new B();

return a;

*/

          //************使用匿名的内部类***************//        //既然内部类的名字,对外部来说没有什么用,可以使用匿名的                       
   IA a = new IA(){        //IA a = new B();定义一个IA的子类,并且实例化了

//内部,必须实现IA接口中的抽象方法

public void fun(){

System.out.println("B-->fun()");

}

};

return a;



//写法的格式:new 接口/抽象类(){//重写方法};



/*return new IA(){

//内部,必须实现IA接口中的抽象方法

public void fun(){

System.out.println("B-->fun()");

}

};

*/

}

}



3.匿名内部类的使用
A:用作方法的实际参数传递:
曾经讲过的方法的形式参数是引用类型的情况,重点是接口的情况,我们知道这里需要一个子类对象(因为父类或者接口无法实例化对象)。
 而匿名内部类就是一个子类匿名对象,所以,可以使用匿名内部类改进以前的做法。


abstract class Person {

public abstract void show();

}



class PersonDemo {

public void method(Person p) {

s.show();

}

}



class PersonTest {



public static void main(String[] args) {

//如何调用PersonDemo中的method方法呢?

PersonDemo pd = new PersonDemo ();

pd.method(new Person() { //传入的不再是一个具体的接口的子类实例化对象,而是一个匿名内部类

public void show() {

System.out.println(“show”);

}

});

}





B:面试题,链式编程法和匿名内部类


interface Inter { 

void show();

}

class Outer {

//补齐代码

}

class OuterDemo {

public static void main(String[] args) {

Outer.method().show();

}

}


要求在控制台输出”HelloWorld”


分析:可以看到最后调用的是一个方法,那么method()也应该是一个对象或者是一个类才可以啊。且outer第一个类名调用的一个方法,那么由此可以得知method()应该是静态,可以由类名直接地调用,
并且该方法返回值应该是一个对象的引用,况且只有接口之中有show方法,由此可以写一个子类实现接口,创建对象(也就是写一个内部类),可以使用匿名内部类,重写接口方法。

Java code?

class Outer{

Public static Inter method{

return new Inter(){

public void show(){

System.out.println("HelloWorld!!!");

}

}



}

}