Java封装2.0——学习记录
分割线接上周
8、内部类
(1)定义:内部类( Inner Class )就是定义在另外一个类里面的类。与之对应,包含内部类的类被称为外部类。
(2)作用:内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类
内部类的方法可以直接访问外部类的所有数据,包括私有的数据
内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
(3)分类:
成员内部类
静态内部类
方法内部类
匿名内部类
示例:
public class HelloWorld {
// 内部类Inner,类Inner在类HelloWorld的内部
public class Inner ()
// 内部类的方法
public void show() {
System.out.println("welcome to imooc!");
}
}
public static void main(String[] args) {
// 创建外部类对象
HelloWorld hello = new HelloWorld();
// 创建内部类对象
Inner i = hello.new Inner();
// 调用内部类对象的方法
i.show();
}
}
注意内部类对象的创建
9、内部类之成员内部类
定义:定义在一个类中的类似于这个类的一个成员变量的内部类成为***成员内部类*成员内部类的使用方法:
例如:
//外部类Outer
public class Outer {
private int a = 99;//外部类的私有属性
//内部类Inner
public class Inner {
int b = 2;//内部类的成员属性
public void test() {
System.out.println( "访问外部类中的a: " +a);
System.out. println("访问内部类中的b:" +b);
}
}
//测试成员内部类
public static void main( String[] args) {
Outer o = new Outer();//创建外部类对象,对象名为o
Inner i = o.new Inner();// 使用外部类对象创建内部类对象,对象名为i
i.test();//调用内部类对象的test方法
}
}
(1) Inner 类定义在 Outer 类的内部,相当于 Outer 类的一个成员变量的位置,Inner 类可以使用任意访问控制符,如 public 、 protected 、 private 等
(2) Inner 类中定义的 test() 方法可以直接访问 Outer 类中的数据,而不受访问控制符的影响,如直接访问 Outer 类中的私有属性a
(3) 定义了成员内部类后,必须使用外部类对象来创建内部类对象,而不能直接去 new 一个内部类对象,即:内部类 对象名 = 外部类对象.new 内部类( );
(4) 编译上面的程序后,会发现产生了两个 .class 文件其中,第二个是外部类的 .class 文件,第一个是内部类的 .class 文件,即成员内部类的 .class 文件总是这样:外部类名$内部类名.class
(5)外部类是不能直接调用内部类的变量和方法的,可先创建内部类的对象,然后通过内部类的对象来访问其成员变量和方法。
(6)如果外部类和内部类具有相同的成员变量或方法,内部类默认访问自己的成员变量或方法,如果要访问外部类的成员变量,可以使用 this 关键字。如:
//外部类Outer
public class Outer {
int b = 1;//外部类中的成员属性b
//内部类Inner
public class Inner {
int b = 2; //内部类的成员属性b
public void test() {
//访问外部类中的成员属性b
System.out.println("访问外部类中的b:" + Outer.this.b);
System.out.println("访问内部类中的b:" +b);
}
}
}
10、静态内部类
定义:被static修饰的内部类成为静态内部类
使用方法:
(1)静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
(2)如果外部类的静态成员与内部类的成员名称相同,可通过***“类名.静态成员”访问外部类的静态成员***(这里和成员内部类是不同的,成员内部类是通过类名.this.变量名来调用的);如果外部类的静态成员与内部类的成员名称不相同,则可通过“成员名”直接调用外部类的静态成员
(3) 创建静态内部类的对象时,不需要外部类的对象,可以直接创建 内部类 对象名= new 内部类();
11、方法内部类:
定义:方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。
例如:
//外部类
public class MOuter {
//外部类中的方法
public void show() {
final int a = 25;//常量
int b = 13;//变量
//方法内部类
class MInner {
int c = 2;//内部类中的变量
public void print() {
System.out.println("访问外部类的方法中的常量a: " +a);
System.out.println("访问内部类中的变量c:" +c);
}
}
MInner mi = new MInner();//创建方法内部类的对象
mi.print();//调用内部类的方法
}
//测试方法内部类
public static void main( String[] args) {
MOuter mo = new MOuter();//创建外部类的对象
mo .show();//调用外部类的方法
}
}
注意:(1)因为是方法内部类不能被除了方法之外所使用,所以不能直接mo.print().应该是mo.show().因为这个内部类是定义在show这个方法中的。
(2)由于方法内部类不能在外部类的方法以外的地方使用,因此方法内部类不能使用访问控制符和 static 修饰符。
12、总结:
(1)只有是成员内部类创建内部类对象时候才需要通过外部类对象来创建。其他都是可以直接创建的。
(2)当外部类和内部类变量重名的话,想要调用外部变量。成员内部类需要(类名.this.变量名)。静态内部类需要是(类名.变量名)
算法题:
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
考点:位运算
思路:
-
首先看十进制是如何做的: 5+7=12,三步走
第一步:相加各位的值,不算进位,得到2。
第二步:计算进位值,得到10. 如果这一步的进位值为0,那么第一步得到的值就是最终结果。 -
第三步:重复上述两步,只是相加的值变成上述两步的得到的结果2和10,得到12。
-
同样我们可以用三步走的方式计算二进制值相加: 5-101,7-111 第一步:相加各位的值,不算进位,得到010,二进制每位相加就相当于各位做异或操作,101^111。
-
第二步:计算进位值,得到1010,相当于各位做与操作得到101,再向左移一位得到1010,(101&111)<<1。
-
第三步重复上述两步, 各位相加 010^1010=1000,进位值为100=(010&1010)<<1。
继续重复上述两步:1000^100 = 1100,进位值为0,跳出循环,1100为最终结果。
代码:
public class Solution {
public int Add(int num1,int num2) {
int sum=0;
int carry=0;
do{
//异或,实现相加但不进位
sum=num1^num2;
//先位与,后左移,相当于进位
carry=(num1 & num2) << 1;
num1 = sum;
num2 = carry;
}while(num2 != 0);
return num1;
}
}