day06 Java面向对象(变量和方法详解1)

1:成员变量和局部变量
    (1)在类中的位置不同
        成员变量:类中方法外
        局部变量:方法定义中或者方法声明上
    (2)在内存中的位置不同
        成员变量:在堆中
        局部变量:在栈中

    (3)生命周期不同
        成员变量:随着对象的创建而存在,随着对象的消失而消失
        局部变量:随着方法的调用而存在,随着方法的调用完毕而消失

    (4)初始化值不同
        成员变量:有默认值
        局部变量:没有默认值,必须定义,赋值,然后才能使用
        

2:匿名对象
    (1)没有名字的对象
    (2)应用场景
        A:调用方法,仅仅只调用一次的时候。
        b:可以作为实际参数传递。
 

public class Student {
      public void show() {
    	  System.out.println("show 方法");
      }
}

 

public class VariableTest {

	public static void main(String[] args) {
		Student stu=new Student();
		stu.show();
		//匿名对象调用方法,匿名对象对象调用完成后就是垃圾,可以被垃圾回收器回收
                new Student().show();
	}

}

 

3:private关键字
    (1)私有的意义,可以修饰成员变量和成员方法
    (2)特点:
        被private修饰的后的成员只能在本类中被访问

  

4:this关键字
    (1)代表当前类的引用对象
        记住:哪个对象调用方法,该方法内部的this就代表那个对象
    (2)this的应用场景:
        A:解决了局部变量隐藏成员变量的问题
     

public class Student {
        private String name;
        private int age;
         //默认的无参构造方法
        public Student() {  
    	
        }
        //自己定义的有参构造方法
        public Student(String name,int age) {  
     	   this.name = name;
    	   this.age = age;
        }  
	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;
	}
      
}

   this 关键字内存图解

 

5:构造方法
    (1)作用:用于对对象的数据进行初始化
    (2)格式:
        A:方法名和类名相同
        B:没有返回值类型,连void都不能有
        C:没有返回值
        
        思考题:构造方法中可不可以有return语句呢?
        可以。而是我们写成这个样子就OK了:return;
        其实,在任何的void类型的方法的最后都可以写上:return;
    (3)构造方法的注意事项
        A:如果我们没写构造方法,系统将提供一个默认的无参构造方法
        B:如果我们给出了构造方法,系统将不再提供默认构造方法

      

 示例:代码:Student s = new Student();做了哪些事情?
    (1)把Student.class文件加载到内存
    (2)在栈内存为s开辟空间
    (3)在堆内存为学生对象申请空间
    (4)给学生的成员变量进行默认初始化。null,0
    (5)给学生的成员变量进行显示初始化。林青霞,27
    (6)通过构造方法给成员变量进行初始化。刘意,30
    (7)对象构造完毕,把地址赋值给s变量

        
6:static关键字
    (1)静态的意思。可以修饰成员变量和成员方法。
    (2)静态的特点:
        A:随着类的加载而加载
        B:优先于对象存在
        C:被类的所有对象共享
        D:可以通过类名调用
            既可以通过对象名调用,也可以通过类名调用。

    (3)静态的内存图
        静态的内容在方法区的静态区


    

   

    (4)静态的注意事项;
               A:在静态方法中没有this对象
               B:静态只能访问静态的成员变量和成员方法

/*
static关键字注意事项
	A:在静态方法中是没有this关键字的
			静态是随着类的加载而加载,this是随着对象的创建而存在。
			静态比对象先存在。
	B:静态方法只能访问静态的成员变量和静态的成员方法
			静态方法:
				成员变量:只能访问静态变量
				成员方法:只能访问静态成员方法
			非静态方法:
				成员变量:可以是静态的,也可以是非静态的
				成员方法:可是是静态的成员方法,也可以是非静态的成员方法。
*/
public class Teacher {
	public int num=10;
	public static int num2=20;
	public void show() {
		System.out.println(num);//隐含表示访问的是成员变量
		System.out.println(this.num);//明确表示访问的是成员变量
		System.out.println(num2);
		function();
		function1();
	}
	
	public static void method() {
		// Cannot make a static reference to the non-static field num
		// 无法从静态上下文中引用非静态 变量 num
		//System.out.println(num);
		System.out.println(num2);
		// Cannot make a static reference to the non-static method function() from the type Teacher
		// 无法从静态上下文中引用非静态 方法 function() 
		//function();
		function1();
	}
	
	public void function() {}
	public static void function1() {}
}


    (5)静态变量和成员变量的区别
        A:所属不同
            静态变量:属于类,类变量
            成员变量:属于对象,对象变量,实例变量
        B:内存位置不同
            静态变量:方法区的静态区
            成员变量:堆内存
        C:生命周期不同
            静态变量:静态变量是随着类的加载而加载,随着类的消失而消失
            成员变量:成员变量是随着对象的创建而存在,随着对象的消失而消失
        D:调用不同
            静态变量:可以通过对象名调用,也可以通过类名调用
            成员变量:只能通过对象名调用

 

7:代码块
    (1)用{}括起来的代码。根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)
    (2)分类:
        A:局部代码块
            在方法中出现 ,用于限定变量的生命周期,及早释放,提高内存利用率。
        B:构造代码块
            在类中方法外出现,把多个构造方法中相同的代码可以放到这里,每个构造方法执行前,首先执行构造代码块。
        C:静态代码块
            在类中方法外出现,并加上static修饰,对类的数据进行初始化,在类加载时就会执行仅仅只执行一次。
    (3)静态代码块,构造代码块,构造方法的顺序问题?
        静态代码块 > 构造代码块 > 构造方法

示例:

/*
代码块:在Java中,使用{}括起来的代码被称为代码块。
根据其位置和声明的不同,可以分为
	局部代码块:局部位置,用于限定变量的生命周期。
	构造代码块:在类中的成员位置,用{}括起来的代码。每次调用构造方法执行前,都会先执行构造代码块。
		作用:可以把多个构造方法中的共同代码放到一起,对对象进行初始化。
	静态代码块:在类中的成员位置,用{}括起来的代码,只不过它用static修饰了。
		作用:一般是对类进行初始化。
*/
class Code {
	static {
		int a = 1000;
		System.out.println(a);
	}
	
	//构造代码块
	{
		int x = 100;
		System.out.println(x);
	}
	
	//构造方法
	public Code(){
		System.out.println("code");
	}
	
	//构造方法
	public Code(int a){
		System.out.println("code1");
	}
	
	//构造代码块
	{
		int y = 200;
		System.out.println(y);
	}
	
	//静态代码块
	static {
		int b = 2000;
		System.out.println(b);
	}
}

public class CodeTest {

	public static void main(String[] args) {
		//局部代码块
		{
			int x = 10;
			System.out.println(x);
		}
		//找不到符号
		//System.out.println(x);
		{
			int y = 20;
			System.out.println(y);
		}
		System.out.println("---------------");
		
		Code c = new Code();	
		System.out.println("---------------");
		Code c2 = new Code();
		System.out.println("---------------");
		Code c3 = new Code(1);

	}

}

打印结果:

10
20
---------------
1000
2000
100
200
code
---------------
100
200
code
---------------
100
200
code1

8:super 关键字

    (1)this和super的区别

            this代表本类对应的引用。

            super代表父类存储空间的标识(可以理解为父类引用)

  (2)用法     

             访问成员变量

                  this.成员变量        super.成员变量

              访问构造方法

                    this(…)                  super(…)

               访问成员方法

                   this.成员方法()       super.成员方法()


9:继承
    (1)把多个类中相同的成员给提取出来定义到一个独立的类中。然后让这多个类和该独立的类产生一个关系,
       这多个类就具备了这些内容。这个关系叫继承。
    (2)Java中如何表示继承呢?格式是什么呢?
        A:用关键字extends表示
        B:格式:
            class 子类名 extends 父类名 {}
    (3)继承的好处:
        A:提高了代码的复用性
        B:提高了代码的维护性
        C:让类与类产生了一个关系,是多态的前提
    (4)继承的弊端:
        A:让类的耦合性增强。这样某个类的改变,就会影响其他和该类相关的类。
            开发的 原则:低耦合,高内聚。
            耦合:类与类的关系
            内聚:自己完成某件事情的能力
        B:打破了封装性
    (5)Java中继承的特点
        A:Java中类只支持单继承
        B:Java中可以多层(重)继承(继承体系)
    (6)继承的注意事项:
        A:子类不能继承父类的私有成员(成员变量和成员方法)
        B:子类不能继承父类的构造方法,但是可以通过super去访问。
   
    (7)Java继承中的成员关系
        A:成员变量
            a:子类的成员变量名称和父类中的成员变量名称不一样

class Father{
	public int num=10;
}

class Son extends Father{
	public int num1=20;// 10,20
	public void show() {
		System.out.println(num);
	    System.out.println(num1);
	}
}

public class ExtendsTest {

	public static void main(String[] args) {
		Son s=new Son();
		s.show();

	}

}


            b:子类的成员变量名称和父类中的成员变量名称一样,怎么访问?
                子类的方法访问变量的查找顺序:
                    在子类方法的局部范围找,有就使用。
                    在子类的成员范围找,有就使用。
                    在父类的成员范围找,有就使用。
                    找不到,就报错。

class Father{
	public int num=10;//10,30
}

class Son extends Father{
	public int num=20;//20,30
	public int num1=30;
	public void show() {
		int num=40;// 40,30
		System.out.println(num);
		System.out.println(num1);
		System.out.println(this.num);//20
		System.out.println(super.num);//10
	}
}

public class ExtendsTest {

	public static void main(String[] args) {
		Son s=new Son();
		s.show();

	}

}


        B:构造方法
            a:子类的构造方法默认会去访问父类的无参构造方法
                是为了子类访问父类数据的初始化
            b:父类中如果没有无参构造方法,怎么办?
                子类通过super去明确调用带参构造
                子类通过this调用本身的其他构造,但是一定会有一个去访问了父类的构造
                让父类提供无参构造


/*
如果父类没有无参构造方法,那么子类的构造方法会出现什么现象呢?
	报错。
如何解决呢?	
	A:在父类中加一个无参构造方法
	B:通过使用super关键字去显示的调用父类的带参构造方法
	C:子类通过this去调用本类的其他构造方法
		子类中一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化。
		
注意事项:
	this(...)或者super(...)必须出现在第一条语句上。
	如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上。
*/
class Father{
	public Father() {
		System.out.println("Father的无参构造");
	}
	
	public Father(String name) {
		System.out.println("Father的带参构造");
	}
}
class Father2{
	
	public Father2(String name) {
		System.out.println("Father2的带参构造");
	}
}
class Son extends Father{
	public Son() {
		//构造方法的第一条默认语句,可以省略不写
		//super();
		System.out.println("Son的无参构造");
	}
	public Son(String name) {
		//构造方法的第一条默认语句,可以省略不写
		//super();
		System.out.println("Son的带参构造");
	}
}
class Daughter extends Father2{
	//mplicit super constructor Father2() is undefined. Must explicitly invoke another constructor
	//父类没有无参构造函数
	public Daughter() {
		//构造方法的第一条默认语句,可以省略不写
		super("任意给");
		System.out.println("Daughter的无参构造");
	}
	//mplicit super constructor Father2() is undefined. Must explicitly invoke another constructor
	//父类没有无参构造函数
	public Daughter(String name) {
		//构造方法的第一条默认语句,可以省略不写
		//super("任意给");
		this();
		System.out.println("Daughter的带参构造");
	}
	
}

public class ExtendsTest {

	public static void main(String[] args) {
		//Son s=new Son();// Father的无参构造    Son的无参构造
		//Son s1=new Son("lwj");//Father的无参构造   Son的带参构造
		//Daughter d=new Daughter();//Father2的带参构造    Daughter的无参构造
		//Daughter d1=new Daughter("lwj");//Father2的带参构造    Daughter的带参构造
		Daughter d2=new Daughter("sss");//Father2的带参构造    Daughter的无参构造   Daughter的带参构造
	}

}

  用例:根据程序写结果

            1  子父类的构造执行过程示例

class Fu{
	static { 
		// 1
    	System.out.println("静态代码块Fu");
    }
    {  
    	//3
    	System.out.println("构造代码块Fu");
    }
    
    public Fu() {
    	//4
    	System.out.println("构造方法Fu");
    }
}


class Zi extends Fu{
    static { 
    	//2
    	System.out.println("静态代码块Zi");
    }
    {  
    	//5
    	System.out.println("构造代码块Zi");
    }
    
    public Zi() {
    	//6
    	System.out.println("构造方法Zi");
    }
}

public class ExtendsTestTwo {

	public static void main(String[] args) {
	/*	静态代码块Fu
		静态代码块Zi
		构造代码块Fu
		构造方法Fu
		构造代码块Zi
		构造方法Zi*/
		Zi z=new Zi();
	}

}

          2   分层初始化示例

/*
	A:成员变量的问题
		int x = 10; //成员变量是基本类型
		Student s = new Student(); //成员变量是引用类型
	B:一个类的初始化过程
		成员变量的初始化
			默认初始化
			显示初始化
			构造方法初始化
	C:子父类的初始化(分层初始化)
		先进行父类初始化,然后进行子类初始化。	
问题:
	虽然子类中构造方法默认有一个super()
	初始化的时候,不是按照那个顺序进行的。
	而是按照分层初始化进行的。
	它仅仅表示要先初始化父类数据,再初始化子类数据。
*/
class X{
	Y b=new Y();
	X(){
		//2
		System.out.println("X");
	}
}

class Y{
	Y(){
		//1//3
		System.out.println("Y");
	}
}


public class ExtendsTestThree extends X {
    Y y=new Y();
    ExtendsTestThree(){
    	//4
    	System.out.println("ExtendsTestThree");
    }
	public static void main(String[] args) {
	
		ExtendsTestThree ett=new ExtendsTestThree();//YXYExtendsTestThree
		
	}

}


        C:成员方法
            a:子类的成员方法和父类中的成员方法名称不一样
            b:子类的成员方法和父类中的成员方法名称一样,怎么访问?
                通过子类对象访问一个方法的查找顺序:
                    在子类中找,有就使用
                    在父类中找,有就使用
                    找不到,就报错

9:方法重写

         子类中出现了和父类中一模一样的方法声明,也称为方法覆盖,方法复写。

/*
	方法重写的注意事项
		A:父类中私有方法不能被重写
			因为父类私有方法子类根本就无法继承
		B:子类重写父类方法时,访问权限不能更低
			最好就一致
		C:父类静态方法,子类也必须通过静态方法进行重写
			
		子类重写父类方法的时候,最好声明一模一样。
*/
class Father {
	//private void show() {}
	
	/*
	public void show() {
		System.out.println("show Father");
	}
	*/
	
	void show() {
		System.out.println("show Father");
	}
	/*
	public static void method() {
		
	}
	*/
	
	public void method() {
		
	}
}

class Son extends Father {
	//private void show() {}

	/*
	public void show() {
		System.out.println("show Son");
	}
	*/
	
	public void show() {
		System.out.println("show Son");
	}
	
	
	public static void method() {
	
	}
	
	/*
	public void method() {
	
	}
	*/
}

class ExtendsDemo10 {
	public static void main(String[] args) {
		Son s = new Son();
		s.show();
	}
}


        

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值