------<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 {
|
2》》》抽象类作为返回值类型:
abstract class Person {
|
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).无法在方法的外部直接实例化局部内部类,但是在方法内是可以的。
在方法外,可以获取局部内部类的对象,但此局部内部类,要实现一个外部定义的接口或继承一个父类;
interface IA |
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).跟局部内部类一样,只是可以省略名字:
|
interface IA //************使用匿名的内部类***************// //既然内部类的名字,对外部来说没有什么用,可以使用匿名的 |
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 {
|
要求在控制台输出”HelloWorld”
分析:可以看到最后调用的是一个方法,那么method()也应该是一个对象或者是一个类才可以啊。且outer第一个类名调用的一个方法,那么由此可以得知method()应该是静态,可以由类名直接地调用,
并且该方法返回值应该是一个对象的引用,况且只有接口之中有show方法,由此可以写一个子类实现接口,创建对象(也就是写一个内部类),可以使用匿名内部类,重写接口方法。
class Outer{
|