黑马程序员——Java要点笔记——面向对象(二)

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

day07 01-面向对象-构造函数-概述

1、构造函数特点:

(1)   函数名与类名相同

(2)   不用定义返回值类型

(3)   没有具体的返回值

2、构造函数:构建创造对象时调用的函数。作用: 可以给对象初始化。

day07 02-面向对象-构造函数-默认构造函数

1、创建对象都必须要通过构造函数初始化。

2、一个类中如果没有定义过构造函数,那么该类中会有一个默认的空参构造函数。

如果在类中定义了指定的构造函数,那么类中的默认构造函数就没有了。如果要需要,那你自己再定义回来。如果自己定义了构造函数,一般都会再定义一个空参构造,防止用户使用出现问题。

day07 03-面向对象-构造函数-构造函数与一般函数的区别

1、一般函数和构造函数有什么区别呢?

答:构造函数:对象创建时,就会调用与之对应的构造函数,对对象进行初始化。

       一般函数:对象创建后,需要函数功能时才调用。

       构造函数:对象创建时,会调用,只调用一次。

       一般函数:对象创建后,可以被调用多次。

2、代码示例

public static void main(String[] args) {
       Person p=new Person();
       p.Person();//不是一般烂,是烂透了。构造函数的作用就是初始化
       p.speak();
       p.speak();
}

3、除了初始化之外,你再用对象去调用构造函数,java会报错。

public class Demo {
    int x=3;
    public static void main(String[] args) {
       Demo d=new Demo();
       d.Demo();
}

报错:

Exception in thread"main" java.lang.Error: Unresolved compilation problem:

    Themethod Demo() is undefined for the type Demo

    at com.itheima.Demo.main(Demo.java:12)

day07 04-面向对象-构造函数-重载

1、什么时候定义构造函数?

答:在描述事物时,该事物一存在就具备的一些内容,这些内容都定义在构造函数中。比如人类的名字、性别。

2、代码示例:

public class Demo {
    public static void main(String[] args) {
       Person p=new Person();
       p.speak();
    }
}
class Person{
    String name=null;
    int age=0;
    Person(){
       name="baby";
       age=1;
    }
    public void speak(){
       System.out.println(name+"...."+age);
    }
}

以及:

public class Demo {
    public static void main(String[] args) {
       Person p=new Person();
       p.speak();
    }
}
class Person{
    public void speak(){
       String name="baby";
       int age=1;
       System.out.println(name+"...."+age);
    }
}

       以上两者都可以在调用speak方法的时候实现同一结果:baby….1

       有何不同?

       第二个之后在调用speak方法的时候,这个对象才有姓名、年龄。如果让他做其他事情的时候,他就没有姓名、年龄。这样不合适。

day07 05-面向对象-构造函数-内存图解

1、分析以下一段代码的内存图解:

class Person{
  String name=null;
  int age=0;
  Person(Stringn,int a){
     name=n;
     age=a;
  }
}

Person p=new Person("小强",10);

       p.speak();


先开辟一块堆内存。


       调用构造函数,构造函数进栈。name=n age=a,他在栈中,无name与age,去堆里找。


构造方法遇到return,弹栈。这时main方法中的p才有了指向。这时Person p=new Person("小强",10);中等号右边的内容才算结束。结束之后p才有了指向。

3、即使你没有定义构造函数,在实例化对象时,构造函数也会进栈。初始化对象,必须会调用一个构造函数,他不进栈,你怎么初始化?!

day07 06-面向对象-构造函数-细节

1、

构造函数与setter方法有何区别?

答:两者不矛盾。一个用来初始化对象,一个用来做后期更改。就像一个人生下来叫“旺财”,后来改名字了,叫“旺旺”,这个就用setter方法改。不然,你每次都用构造方法,这不要投胎了么。

2、回答以下两个问题:

Person()

{……}

Public void speak()

{……}

(1)   Person()中能调用speak()吗?

可以。

(2)   speak()中能调用Person()吗?

不能!Person只用于初始化,只在new对象的时候调用一次。

4、Person(){……}

void Person(){……}//加了void之后,这个函数就不是构造函数了,但你也不能说他错。

5、写一般函数,第一个单词首字母小写,构造函数首字母大写(因为类名第一个单词首字母大写,与类名一致)

6、定义完有参构造后,无参构造自动消失,你需要的话自己再手动定义一个。

7、构造函数中有return语句吗?

答:有!return用来结束函数的,所有函数都有return,你不写他也有。所有函数全有return,return后面不跟任何东西的话,起结束函数的功能。

8、分析以下代码的运行结果:

public class Demo {
    public static void main(String[] args) {
       Person p=new Person();
       p.Person();
    }
}
class Person{
    Person(){
       System.out.println("构造");
    }
    void Person(){
       System.out.println("普通");
    }
}

运行结果:构造

                 普通

day07 07-面向对象-this关键字-使用场景1-&this原理图解

1、this到底代表啥?

       this代表对象,代表哪个对象呢?

代表当前对象。

this就是所在函数,所属对象的引用。this是一个引用!

简单来说,哪个对象调用了this所在的函数,this就代表哪个对象。

2、this原理图解

public class Demo05 {
    public static void main(String[] args) {
       Person p=new Person("旺财");
       p.speak();
    }
}
class Person{
    String name;
    int age;
    Person(String name){
       this.name=name;
    }
    void speak(){
       System.out.println("名字是:"+name+"年龄是:"+age);
    }
}


       个人觉得,this并不完全等于p。this先于p有指向。因为构造函数未完成时,p还没有指向,但是this可用。


都省略了this。其实this被隐含了,但是若像上面name=name;出现了歧义,Java不知道给谁加this了,或者要不要加this了。这时,就需要你手动加,来告诉java哪个是堆里成员变量,哪个是局部变量。

3、参数列表中的name是局部变量,this.name是通过this这个引用找到了对应堆内存中的成员变量name。


day07 08-面向对象-this关键字-使用场景2-以及细节

1、构造函数可以调用一般函数。一般函数不能调用构造函数。那么构造函数与构造函数之间如何访问呢?

2、

3、  图解

public class Demo05 {
    public static void main(String[] args) {
       Person p=new Person("旺财",20);
       p.speak();
    }
}
class Person{
    String name;
    int age;
    Person(String name){
       this.name=name;
    }
    Person(String name,int age){
       this(name);
       this.age=age;
    }
    void speak(){
       System.out.println("名字是:"+name+"年龄是:"+age);
    }
}

    


   方法会先从自己的栈内存中找name,找不到再到堆中去找。若在自己的栈中找到了,出现了歧义,我加上一个this,让他强制去找堆中的成员变量。




4、  this的使用场景2:this也可以用于在构造函数中,调用其他构造函数。(构造调用构造时才用)

5、  注意①:这种情况,this只能定义在构造函数的第一行!因为初始化动作要先执行。

6、  解释注意①:


7、  注意②:this()调用防止死循环调用,要记得留一个出口。

不留出口,会导致程序停下来,因为栈内存溢出了。无穷无尽的进栈,无人出栈。

day07 09-面向对象-this关键字-应用

1、this经典应用:可用this判断是否是同龄人。判断两个对象是否相等。

2、该代码方法应该只有一个参数。我与张三比,我有compare这个功能,你再把我作为参数搞进去干啥。而应该是由我来调用这个方法,把你张三作为参数传进来。

3、代码:

public boolean compare(Person p){
       return this.age==p.age;
}

day07 10-面向对象-static关键字-数据共享

1、static本身是一个关键字,也是一个修饰符。他可以修饰成员变量、成员函数、内部类。

2、示例:

class Person{
    String name;
    String country="CN";
    public void show(){
       System.out.println(country+";"+name);
    }
}
public class Demo06 {
    public static void main(String[] args) {
       Person p=new Person();
       p.name="小强";
       p.show();
    }
}

day07 11-面向对象-static关键字-特点

1、static修饰的内容,可被类名直接调用。

2、那我全静态不就好了,还省的写对象。这种思想对吗?

错误!你static name为小强。那所有的人类都得叫小强吗?明显不行!

3、  static的特点

①static是一个修饰符,用于修饰成员。(成员变量和成员方法)

②static修饰的成员被所有的对象所共享。

③static优先于对象存在,因为static的成员随着类的加载就已经存在了。

④static修饰的成员多了一种调用方式,就是可以直接被类名所调用。

⑤static修饰的数据是共享数据,对象中存储的是特有数据。

day07 12-面向对象-static关键字-成员变量和静态变量的区别

1、成员变量和静态变量的区别

①两个变量的生命周期不同

              成员变量随着对象的创建而存在,随着对象的被回收而释放。

              静态变量随着类的加载而存在,随着类的消失而消失。类在,静态变量就一直在。

②调用方式不同

              成员变量只能被对象调用。

              静态变量可以被对象调用,也可以被类名调用。

③别名不同

              成员变量也称为实例变量。

              静态变量也称为类变量。

④数据存储位置不同

              成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据。

              静态变量数据存储在方法区(共享数据区)的静态区中,所以也叫对象的共享数据。static所修饰的变量被多个对象所共享。

3、  代码示例:

public class TestDemo08 {
    public static void main(String[] args) {
       Person per1=new Person();
       per1.talk();
       per1.country="JP";
       per1.talk();
       Person per2=new Person();
       per2.talk();
    }
}
class Person{
    int age=10;
    static String country="CN";
    void talk(){
       System.out.println("age:"+age+"_country:"+country);
    }
}

    运行结果:

    age:10_country:CN

    age:10_country:JP

    age:10_country:JP

    虽然只是per1将country从CN改成了JP,但由于country是共享数据,per2打印出来的也是JP。

day07 13-面向对象-static关键字-注意事项

1、静态使用的注意事项(静态的使用,绝对不牵涉到事先要有对象,不牵涉到堆内存,也就不牵涉到this、super这些引用指向)

①静态方法只能访问静态成员(非静态既可以访问静态,又可以访问非静态)。这成员包含两部分,一个是变量,一个是函数。

       因为静态不用对象,而非静态成员在对象的创建时才会出现。

②静态方法中不可以使用this或者super关键字。

       this、super可以调用构造函数,所以不行。this代表对象的堆内存地址。

③主函数是静态的。

2、代码示例


3、代码示例

public class TestDemo09 {
    public static void main(String[] args) {
       Person.talk();
    }
}
class Person{
    int age=10;
    static String country="CN";
    static void talk(){
       Person per=new Person();
       System.out.println("age:"+per.age+"_country:"+country);
    }
}

    运行结果:age:10_country:CN

       静态方法talk(),通过对象调用非静态变量age完全没有问题(主方法其实也类似)。

4、代码示例

    public static void main(String[] args) {
       int x=0;
       System.out.println(x);
    }

    ok。与静态方法只能调用静态变量不矛盾。这里说的调用,你在内部定义,再用它不算调用。在静态方法中new对象去调用也没关系。

day07 14-面向对象-static关键字-main函数解析

1、public static void main(String[]args)

2、主函数的特别之处:①、格式是固定的②、被jvm所识别和调用。

3、public:因为全县必须是最大的

4、static:不需要对象的,直接用主函数所属类名调用即可。

5、void:主函数没有具体的返回值

6、String[]  args:这是主函数的参数列表,是一个数组类型的参数,而且元素都是字符串类型。

7、args只是一个名字

public static void main(String[] x)都OK。

8、public static void main(String[]args)

   public static void main(String[] x)

       挂了,到底哪个是入口?JVM无法分清。

9、

    public static void main(String[] args) {
       int x=0;
       System.out.println(x);
    }
    public static void main(int x) {
       int z=1;
       System.out.println(z);
    }

运行结果:0

       可见,虽然有重载,但是java仍然从main(String args[])处开始。

day07 15-面向对象-static关键字-内存图解

1、代码示例

class Person{
    private String name;
    private int age;
    static String country="CN";
    public Person(String name,int age){
       this.name=name;
       this.age=age;
    }
    public void show(){
       System.out.println(Person.country+";"+this.name+";"+this.age);
    }
    public static void method(){
       System.out.println(Person.country);
    }
}
public class TestDemo11 {
    public static void main(String[] args) {
       Person.method();
       Person p=new Person("java",20);
       p.show();
    }
}

2、





       全部搞完后,main方法最后有return,main方法弹栈。

3、代码示例:

public class TestDemo12 {
    public static void main(String[] args) {
       Person per=new Person();
       per.talk();
       Dog d=new Dog();
       d.talk();    
    }
}
class Person{
    static String name="人";
    public void talk(){
       System.out.println(name);
    }
}
class Dog{
    static String name="狗";
    public void talk(){
       System.out.println(name);
    }
}

运行结果:人

                狗

       Person类中定义的static变量只对这个类的对象有用。static变量是被给雷的对象来共享的。

day07 16-面向对象-static关键字-什么时候用

1、静态(static)什么时候用?

①静态变量

       (不加静态在堆内存的对象中,加了静态在方法区中。不加静态,对象特有;加了静态,对象共有)静态变量放置内存浪费,不用在每个对象中都去定义,我只定义一个,归这个类所有的对象共有。

       当分析对象中所具备的的成员变量的值都是相同的。这时这个成员就可以被静态修饰(对象特有跟对象共有的区别)。

       只要数据在对象中都是不同的,就是对象的特有数据,必须存储在对象中,是非静态的。如果是相同的数据,对象不需要做修改,只需要使用即可,不需要存储在对象中。(你要是全静态,就意味着不是共性的数据,也被共性了)定义成静态的。

②静态函数

       (我对外提供的函数,到底是静态的呢,还是非静态的呢?)看他调用的数据类型。

       函数是否用静态修饰,就参考一点,就是该函数功能是否有访问到对象中的特有数据。

       简单点说。从源代码看,该功能是否需要访问非静态的成员变量,如果需要,该功能就是非静态的。如果不需要,就可以将该功能定义成静态的。当然,也可以定义成非静态的。

       但是非静态需要被对象调用,而仅创建对象调用非静态的,没有访问特有数据的方法,该对象的创建是没有意义的。(非静态不需要对象,直接用类名调用即可)

day07 17-面向对象-static关键字-静态代码块

1、static{……}直接写在类中。

2、静态代码块,随着类的加载而执行,类只要一加载,就执行这个代码块。

3、静态代码块的作用:用于给类初始化。

       有些类,是没必要创建对象的。例如类中成员皆静态,我创建这个类的对象就没意义了。那我不创建对象,就不能调用构造函数,那我咋初始化。答:用静态块给类初始化。但这种初始化方式用的不多。

4、如果静态块写到了主类中呢?

public class TestDemo13 {
    static{
       System.out.println("a");
    }
    public static void main(String[] args) {
       System.out.println("b");
    }
}

运行结果:a

                b

       可见,这里仍然先执行静态块,之后再执行主方法。主类一旦被创建,静态块就没执行了。

day07 18-面向对象-构造代码块

1、直接定义在类里面的代码块——构造代码块

2、构造代码块的作用:给该类的所有对象初始化。某部分相同的初始状态,但后期对象仍可以修改成自己各自独特的属性。

3、构造函数是给对应的对象进行针对性的初始化。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值