Java基础知识(面向对象——学习笔记二)

查漏补缺:

变量:
    根据变量声明的位置不同 将变量分为局部变量  成员变量(实例变量 、 全局变量)
    局部变量:声明在方法中的 或者是代码块中的变量 称之为局部变量(方法中的形参也是隶属于方法的局部变量)
        只能在当前方法中有效 出了这个方法无效
        局部变量 要在声明且赋值 才能够正常使用
        
        代码块:
            一组大括号括起来的就称之为代码块  {} 
            声明在方法中的代码块称之为 局部代码块: 作用:减少变量的生命周期  降低系统的内存开销
    成员变量:
        定义在类中 方法外  作用范围在整个类中有效,存在默认值
            byte   short   int    long     ( 默认为 0)
            float   double  (默认为 0.0)
            char   (默认为 '\u0000'  空格)
            boolean  (默认为  false)
            引用   (默认为 null )

构造器:
    特点:
        通过new关键词调用构造器可以产生当前类的实例/对象
    构造器的注意事项:
        1、构造器方法不需要些返回值类型
        2、方法的名称和类名保持一致
        3、无需在方法内部显式的返回当前对象
        4、如果在一个类中不写构造器  默认存在一个 空构造器  无参构造器    
        5、如果在类中显式声明一个构造器 那么默认的构造器就不存在了 (建议 写类的时候一定要保证空构造器的存在)
        6、构造器可以重载
this:(当前对象)
    this.
        可省略:
        不可省略:
            出现同名变量,this. 用来区分同名变量的
    this() 调用构造器的
        在类中无法通过构造器的名称直接调用构造器
        注意点: this()必须要在构造器的首行编写

继承:
    子承父业
    作用: 提高了代码的复用性
    使用: 子类 extends 父类
    注意: 子类可以使用父类中定义的属性以及方法  子类中也可以定义自己独有的功能和属性
    java中只支持单继承 一个类只能有一个直接父类
        
    思考: 复用性没有那么强 ,为什么还需要继承? 维护的一种关系-> is a 
     答:  维护了逻辑关系 并且可以让我们更好的通过面向对象去梳理系统之间的关系(因为java只能继承一个类,所以复用性不是很强,那为什么它还是面向对象的三大特征之一呢?在实际运用中我们主要使用继承去维护一种逻辑关系。)
    面试问题: A-> B  后期迭代过程中发现A->C更优 解决办法?

   目前自己的想法为:采用组合技术,在B中实例化C


    一个类没有显式的继承其他类 那么默认父类是Object 我们讲Object称之为所有类的超类 父类 基类 

    方法重写:
        父类中的功能不满足子类的需要 子类重写
        
    super: 代指父类对象
        super.
            可省略:
            不可省略:区分子类和父类中中的同名方法/同名变量
        super():调用父类构造器的
         默认调用父类的空构造器, super()必须要在构造器的首行
         
    super()和this() 如何都能发挥作用?
    千万注意super()和this()不能同时出现 有super就没有this 有this就没有super。
    如何都发挥作用:保留this() 通过this调用的构造器中 持有一个super的指向。

包:
    为什么需要包呢?用于区分类的
    一个类中顶头写 package 声明当前类从属于那个包
    

导包:
    为什么要导包? java中是以类为单位的  如何区分一个类,通过全限定名  包名.类名
    通过import关键词 + 全限定名  在声明类前 添加这行代码
    
    如何导入同名类?
        只能有一个类通过导包方式导入,其他同名的类 通过全限定名操作
        com.公司名.oop.Scanner sc = new com.公司名.oop.Scanner();    (如果已经引入系统Scanner对应的包,可以通过此种方式引入自己写的类)
        
        如何静态导入?(java1.5之后加入)
        import static java.lang.Math.PI;

            
封装:
    4个关键词
                             本类        同包子类        同包            异包子类        异包
                    
        public              √                  √               √                       √               √
        protected         √                 √               √                       √                ×
        默认的             √                 √               √                       ×                ×
        private             √                  ×              ×                       ×                ×
         
        封装: 调用者而言: 降低了调用的复杂度  降低了学习成本   
               被调用者而言:增加了被调用者安全系数   维护内部系统的稳定性
            
               继承在一定程度上了破坏了封装性   
多态 : 多种形态  
        1、继承关系
        2、子类要重写父类的方法
        3、父类变量指向了子类对象
       

static:

public class Test05 {
	
	public static void main(String[] args) {
		
		F f=new F();
		F f1=new F();
	}

}
class F{
	static{
		System.out.println("静态代码块。。");
	}
	{
		System.out.println("初始化块。。");
	}
	public F(){
		this(4);
		System.out.println("无参数的构造方法");
	}
	public F(int num){
		System.out.println("带参数的构造器。。");
	}
}
静态代码块。。
初始化块。。
带参数的构造器。。
无参数的构造方法
初始化块。。
带参数的构造器。。
无参数的构造方法

总结分析:

1、一个类中的静态代码块是最先加载的,但是只会加载一次

2、初始化代码块会优先于构造器执行,编译阶段初始化代码块会存在于构造器的首行(我们可以使用反编译工具对编译代码进行查看)

3、static修饰的成员是隶属于类的,是类和对象共享的

4、以上代码无参数的构造器会调用带参数的构造器,this();需要放在无参构造器的首行。而编译器编译时是将初始化代码块放在构造器的首行,此时会不会冲突呢?情况是这样的:编译器编译时,编译到this();语句之后,知道程序会执行带参数的构造器,于是将初始化的代码块放在带参数的构造器的首行。

public class Test05 {
	
	public static void main(String[] args) {
		
		System.out.println(S.num);
        System.out.println("====================");
		System.out.println(S.number);
	}

}
class S{
	static final int num=10;
	static final int number=(int)(Math.random()*10);
	static{
		System.out.println("我被执行了。。");
	}
}
}
10
====================
我被执行了。。
9

总结分析:

调用静态内容类会不会加载?

1、如果调用的静态内容是一个常量值,常量值是一个字面值,那么该常量会在编译期间确定其值,访问时就不会导致类加载(常量值得意思就是该内容被final修饰了)。(编译期静态常量不会导致类加载)

2、如果调用的静态内容不是一个字面常量值,那么该常量会在加载时确定,调用就会导致类加载。(非编译期静态常量会导致类加载)

请解释:可以在非static方法中使用static内容   但是不能在static内容中使用非static内容

因为静态内容会优先于非静态的内容加载,静态内容不能去使用还没有加载出来的内容。

请问:现有类还是先有对象

答:1、对于编码来说:先有类再有对象

        2、对于构建来说:先有对象再抽象出类

注意:编译看左边 运行看右边      动态联编

equals:

如何判断字符串是不是空串?     "".equals(str)

String equals()方法源码分析:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                //此处为什么不在原字符串的基础上进行比较?
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

解答以上问题:

按照一贯逻辑思维,会直接在原字符数组上进行比较。源码中采用先赋值给局部变量,再进行比较的好处是:value值属于全局变量,生命周期更长,局部变量的生命周期更短相对于全局变量。现在赋值给局部变量来做,如果value在别处不再有引用,那么gc就会自动对他进行回收,节约了内存空间的消耗。

问题:为什么非静态内部类中不能有static成员变量却可以有static final 属性的编译期常量?

参考文献:https://blog.csdn.net/wuchangi/article/details/79182850

                  https://www.jianshu.com/p/4dbe68850e1b

猜你喜欢

转载自blog.csdn.net/ToBe_Coder/article/details/81365965