类与对象要点 万字总结 + 代码实例 ---- JavaSE面向对象编程

目录

1. 类与对象的定义及使用

1.1 类与对象的概念

1.2 类与对象的定义与使用

1.3 内存区域划分

1.4 引用传递 

2. 封装与构造方法

2.1 private 实现封装

2.2 编写类的规则要求

2.3 构造方法

2.4 构造方法与方法重载 

2.5 匿名对象

3. this 关键字

 3.1 this 调用本类属性

3.2 this 调用本类方法

3.2.1 this 调用普通方法

3.2.2 this 调用构造方法 

3.3 this表示当前对象的引用

4. static 关键字(重要)

 4.1 static 修饰变量(类属性)

 4.2 static 方法(类方法)

 4.3 修饰代码块

 4.4 修饰内部类

5. 代码块(重要)!!!

 5.1 普通代码块

5.2 构造块

5.3 静态块

 5.3.1 非主类中的静态块

 5.3.2 主类中的代码块

5.4 同步代码块 

6. 内部类的定义及使用

6.1 内部类的概念 

6.2 内部类为什么存在

6.3 内部类与外部类的关系

6.4 内部类的使用

6.4.1 内部类分类

6.4.2 使用内部类时创建内部类对象

6.4.3 在外部类的内部创建内部类对象

6.5 内部类详解 

6.5.1 成员内部类

6.5.2 静态内部类

6.5.3 方法内部类

6.5.4 匿名内部类

7. final 关键字


面向对象编程三大特征:

        1. 封装性

        2. 继承性

        3. 多态性

1. 类与对象的定义及使用

1.1 类与对象的概念

类 就是指共性的概念,一类事物的总称。

对 象指一个具体的事物,类的一个实例。

1.2 类与对象的定义与使用

定义: 

class 类名称 {
    属性1;
    属性2;
    ... ...;

    方法1(){}
    方法2(){}
    ... ...
}

 例子:

class Person {
    public String name;
    public int age;
    
    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
}

class Person {
    public String name;
    public int age;

    public  Person() {
    }
    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public static void main(String[] args) {
        Person person1 = new Person();
        Person person2 = new Person("张三",24);
    }
}

产生对象:类名称  对象名称  =  new  类名称 (); 

 注意此处:有new,就表明开辟了新空间

 

1.3 内存区域划分

大体上,可以将内存分为栈内存和堆内存。 

1. 栈内存:存放局部变量(基本数据类型、对象的引用-->堆内存的引用等)

2. 堆内存:new出来的

举例:

Person person1 = new Person();
        person1.name = "张三";
        person1.age = 24;

 

1.4 引用传递 

如果,代码变成这个样子呢?

Person person1 = new Person();
Person person2 = new Person();
person2 = person2;

  

 引用传递其实就是一块堆内存可以被多个栈内存所指向。

2. 封装与构造方法

2.1 private 实现封装

 上述代码中,类的属性和方法对外部可见,现实生活开发中,部分属性(比如说密码)及方法是不允许对用户可见的,因此引入了封装很有必要,体现了保护性

将上述代码改写为:

 属性或方法的可见不可见根据现实情况来决定。

 此时,使用private 对类的属性进行了封装,如果要访问这个私有的属性,就必须提供以下方法:

Getter: 对属性内容的获得

Setter: 对属性内容进行设置、修改

例子:

class Person {
    private String name;
    private int 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;
    }

    public void print(){
        System.out.println("姓名:" + name + ": 年龄:" + age);
    }
}
public class Text {
    public static void main(String[] args) {
        Person person1 = new Person();
        person1.setName("张三");
        person1.setAge(24);
        person1.print();
    }
}

 如果不添加setter 和 getter 方法,会发现代码报错,Text主类无法访问另外一个类中的属性。

因此我们可以得出,private 实现封装,只允许本类访问,外部类无法访问。

2.2 编写类的规则要求

1、编写类时,类中所有的属性都使用private 封装。

2、属性若要被外部访问,需定义setter 、 getter方法。 

2.3 构造方法

 产生对象:类名称  对象名称  =  new  类名称 (); 

所谓构造方法就是在使用new关键字实例化新对象的时候,由进行调用的方法。

需要遵循原则:

1. 方法名与类名称相同。

2. 构造方法没有返回值类型声明

3. 每个类中至少有一个构造方法,如果开发者没有明确定义构造方法, 系统会自动生成一个无参构造。

问题:构造方法没有返回值,为什么没有void 声明?

答:1、属性是在对象开辟堆内存时开辟的空间

        2、构造方法是在创建对象(即new)时被调用的

        3、普通方法是在空间开辟构造方法之后才可以多次调用的

编译器是根据程序的结构来区分普通方法和构造方法的,所以在构造方法之前没有返回值类型声明。 

构造方法的调用和对象内存分配几乎是同时进行的,可以利用构造方法来为类中的属性进行初始化操作,从而避免多次setter调用。 

2.4 构造方法与方法重载 

成员方法不能调用构造方法!

成员方法有对象才能使用,而构造方法是产生对象时调用的方法。 

2.5 匿名对象

//有名字的对象
Person person1 = new Person();
//匿名对象
new Person();
new Person().name;

有名字的对象可以多次使用,而匿名对象使用一次之后就会成为垃圾,由垃圾回收器在空闲的时候回收。 匿名对象在开发中较为少见。

3. this 关键字

1、this 调用本类属性

2、 this 调用本类方法

        2.1、 this 调用类中的成员方法

        2.2、 this 调用构造方法

3、 this 表示当前对象

 3.1 this 调用本类属性

class Person {
    private String name;
    private int age;


    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }

    public void print(){
        System.out.println("姓名:" + name + ": 年龄:" + age);
    }
}
public class Text {
    public static void main(String[] args) {
        Person person1 = new Person("张三",24);
        person1.print();
    }
}
输出:
姓名:张三: 年龄:24

 从上述代码可以得出:当参数与类中属性同名时,类中的属性无法被正确赋值,此时需要加上this关键字,就可以给对象属性赋值。

注意:只要是在类中访问类中的属性,一定要加上this 关键字。 

3.2 this 调用本类方法

3.2.1 this 调用普通方法

3.2.2 this 调用构造方法 

class Person {
    private String name;
    private int age;

    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }

    public void fun() {
        System.out.println("你好");
    }
    public void fun(String name) {
        System.out.println("你好");
        this.name = name;
    }
    public void fun(String name,int age) {
        System.out.println("你好");
        this.name = name;
        this.age = age;
    }
    public void print(){
        //调用成员方法
        this.fun();
        System.out.println("姓名:" + name + ": 年龄:" + age);
    }
}

 会发现上述代码中,多次重复写同样的语句,出现代码冗余,因此使用this调用构造方法。

 注意:1. this(参数);要放在方法的首行

           2. 构造方法的相互调用不能形成环。

3.3 this表示当前对象的引用

class Person {
    private String name;
    private int age;
    public Person() {
    }
    public Person(String name,int age) {
        this.name = name;
        this.age = age;
    }
    public void fun() {
        System.out.println(this);
    }
}
public class Text {
    public static void main(String[] args) {
        Person person1 = new Person();
        Person person2 = new Person();
        System.out.println(person1);
        person1.fun();
        System.out.println(person2);
        person2.fun();
    }
}
输出
Person@1b6d3586
Person@1b6d3586
Person@4554617c
Person@4554617c

当前的属性或者方法是通过哪个引用操作的,this 就表示该引用。 

4. static 关键字(重要)

 4.1 static 修饰变量(类属性)

class Person {
    String name;
    int age;
    String Country = "中国";
    public void print() {
        System.out.println("姓名:" + this.name + "年龄:" + this.age);
    }
}
public class Text {
    public static void main(String[] args) {
       Person person1 = new Person();
       person1.name = "张三";
       person1.age = 24;
        Person person2 = new Person();
        person2.name = "李四";
        person2.age = 18;
        person1.print();
        person2.print();
    }
}
输出:
姓名:张三年龄:24
姓名:李四年龄:18

内存:

 表示所有对象都具有的属性,在属性前面添加static 关键字即可。

 在公共属性前添加static关键字之后,内存分配:

 结论:

1. 访问static 属性,应使用 类名称 . 属性名

2. static与对象无关

 4.2 static 方法(类方法)

class Person {
    String name;
    int age;
    static String Country = "中国";
    public static void setCountry(String c) {
        Country = c;
    }
    public void print() {
        System.out.println("姓名:" + this.name + "年龄:" + this.age + this.Country);
    }
}
public class Text {
    public static void main(String[] args) {
       Person person1 = new Person();
       Person.setCountry("美国");
       person1.print();
    }
}
输出:
姓名:null年龄:0美国

 注意:

static 方法不能调用非static定义的属性或者方法,但是非static 方法可以访问static 方法或者属性。

 4.3 修饰代码块

(下文)

 4.4 修饰内部类

(下文)

5. 代码块(重要)!!!

 5.1 普通代码块

普通代码块:定义在方法,直接用 { }  括起来的代码就叫普通代码块。 

 一般因为方法中代码太长,为了避免变量重名会使用普通代码块。(使用较少)

5.2 构造块

 构造块: 定义在类中,使用{ } 括起来的部分代码,叫做构造代码块。

 构造块与构造方法的执行顺序:

class Person {
    private String name;
    private int age;
    public Person() {
    }
    public Person(String name,int age) {
        System.out.println("构造方法");
        this.name = name;
        this.age = age;
    }
    {
        System.out.println("构造块");
    }
}
public class Text {
    public static void main(String[] args) {
        Person person1 = new Person("张三",24);
    }
}
输出
构造块
构造方法

先执行构造块,后执行构造方法。

有几个对象产生,构造块就执行几次。 

5.3 静态块

 静态代码块:定义在类中,使用static 定义的代码块。

 5.3.1 非主类中的静态块

class Person {
    private String name;
    private int age;
    public Person() {
    }
    static {
        System.out.println("静态块");
    }
    public Person(String name,int age) {
        System.out.println("构造方法");
        this.name = name;
        this.age = age;
    }
    {
        System.out.println("构造块");
    }
}
public class Text {
    public static void main(String[] args) {
        Person person1 = new Person("张三",24);
        Person person2 = new Person("李四",18);
    }
}

输出
静态块
构造块
构造方法
构造块
构造方法

优先于构造块执行,与对象无关。

无论产生多少实例化对象,静态块只执行一次。 

 5.3.2 主类中的代码块

public class Text {
    static {
        System.out.println("主类中的静态代码块");
    }
    public static void main(String[] args) {
        new Text();
        System.out.println("主方法");
    }
输出:
主类中的静态代码块
主方法

主类中的静态块,优先于主方法(main)执行。 

5.4 同步代码块 

6. 内部类的定义及使用

 内部类:在一个类的内部进行其他类结构的嵌套操作

6.1 内部类的概念 

不含内部类:

class Outer {
    private String msg = "你好";
    public String getMsg() {
        return this.msg;
    }
    public void fun() { //3. 调用Inner中的print方法
        Inner in = new Inner(this);
        in.print();
    }
}
class Inner {
    private Outer out;
    public Inner(Outer out) {
        this.out = out;
    }
    public void print() {
        System.out.println(out.getMsg()); // 4. 执行此方法
    }
}
public class Text {
    public static void main(String[] args) {
       Outer out = new Outer(); //外部类对象 1. 实例化Outer类对象
       out.fun(); //外部类方法 2. 调用Outter类方法
    }
}

 内部类:

class Outer {
    private String msg = "你好";
    class Inner { //定义一个内部类
        public void print() {
            System.out.println(msg);
        }
    }
    public void fun() { //外部类中的方法
        Inner in = new Inner();//内部类对象
        in.print();//内部类提供的方法
    }
}
public class Text {
    public static void main(String[] args) {
       Outer out = new Outer(); //外部类对象
       out.fun(); //外部类方法
    }
}

上述代码实现了相同的功能,主方法代码没变,只是把内部类拆开到外部。 由此发现,引入内部类之后,程序变得有些混乱,但是方便操作外部类的访问。

6.2 内部类为什么存在

1. 内部类方法可以访问该类定义所在作用域中的数据,包括被private修饰的私有数据。

 2. 内部类可以对同一包中的其他类隐藏起来。

3. 内部类可以实现java单继承的缺陷。

4. 需要回调函数可以使用匿名内部类来避免大量的代码。

6.3 内部类与外部类的关系

1. 对于非静态内部类,内部类的创建依赖外部类的实例对象,在没有外部类实例之前是无法创建内部类的。

2. 内部类是一个相对独立的实体,与外部类不是继承的关系。

3. 内部类可以直接访问外部类的元素(包含私有域),但是外部类不能直接访问内部类的元素。内部类与外部类可以相互访问彼此的私有域(内部类访问外部类的私有域可以直接访问,外部类访问内部类的私有域必须通过内部类对象访问)

4. 外部类可以通过内部类引用间接访问内部类元素。 

内部类可以访问外部类的私有域:

class Outter {
    private String outName;
    private int outAge;

    class Inner {
        private int  InnerAge;
        public Inner() {
            Outter.this.outName = "张三";
            Outter.this.outAge = 20;
        }
        public void print() {
            System.out.println(outName);
            System.out.println(outAge);
        }
    }
}

public class Text {
    public static void main(String[] args) {
       Outter.Inner inner = new Outter().new Inner();
       inner.print();
    }
}

 外部类可以通过内部类引用间接访问内部类元素:

class Outter {
    public void print() {
        Inner inner = new Inner();
        inner.print();
    }

    class Inner {

        public void print() {
            Inner inner = new Inner();
            System.out.println("张三");
        }
    }
}

public class Text {
    public static void main(String[] args) {
       Outter.Inner inner = new Outter().new Inner();
       out.print();
    }
}

6.4 内部类的使用

6.4.1 内部类分类

1. 成员内部类

2. 静态内部类

3. 方法内部类

4. 匿名内部类 

6.4.2 在外部类的外部创建内部类对象 

 

6.4.3 在外部类的内部创建内部类对象

6.5 内部类详解 

6.5.1 成员内部类

用法和成员方法差不多,只不过是个类 

注意:

1. 成员内部类中不能存在任何static的变量和方法。

2. 成员内部类是依附于外部类的,所以只有先创建了外部类才能创建内部类。 

3. private 不可以用在外部类的声明,但是可以用在内部类的成名(就像成员变量可以使private)

5. 

 成员内部类不能拥有静态域,但是可以访问外部类的静态

 

 

6.5.2 静态内部类

使用static修饰的内部类称为静态内部类非静态内部类在编译完成之后会隐含一个引用,该引用指向它的外部类 ,而静态内部类没有这个引用,即就是说:

1. 静态内部列的创建不需要依赖于外部类,可以直接创建。

2. 静态内部类不可以使用任何外部类的非static成员变量及方法,而非静态内部类则都可以。

3. 成员内部类可以访问外部静态域,但不能拥有静态域

4. 静态内部类可以拥有成员域,但不能访问外部类的成员域

class Outter {
    private static String msg = "你好";

    static class Inner { // 定义一个内部类 ,只能使用外部类的static属性及方法
        public void print() {
            System.out.println("张三");
        }
    }
    //在外部类中定义方法,实例内部类对象
    public void fun() {
        Inner inner = new Inner();
        inner.print();
    }
}

public class Text {
    public static void main(String[] args) {
       Outter.Inner inner = new Outter.Inner();
       inner.print();
    }
}

6.5.3 方法内部类

  方法内部类定义在外部类的方法中,只能在该方法中被使用,出了该方法就失效。

对这个类的主要使用就是应用与解决比较复杂的问题,但又不希望这个类是公共可用的,就产生了局部内部类。 

1. 对外部完全隐藏,因此方法内部类不能有任何访问修饰符

代码实例:

class Outter {
    private int num;
    public void fun(int test) {
        class Inner {
            private void print() {
                num++;
                System.out.println(num);
                System.out.println(test);
            }
        }
        new Inner().print();
    }
}

public class Text {
    public static void main(String[] args) {
       Outter out = new Outter();
       out.fun(20);
    }
}
输出:1  20

6.5.4 匿名内部类

 匿名内部类就是一个没有名字的方法内部类,因此匿名内部类具有方法内部类所有的约束。

注意:

        1. 匿名内部类是没有访问修饰符的。

        2. 匿名内部类必须继承一个抽象类或者实现一个接口。

        3. 匿名内部类中不能有static。

        4. 匿名内部类是没有构造方法,因为没有类名。

        5. 与局部内部类相同,匿名内部类也可以引用方法形参,该形参声明为final。 

        6. 使用一次就销毁了

代码实例:

interface MyInterface {
    void test();
}
class Outter {
    private int num;
    public void fun(int test) {
        new MyInterface() {
            @Override
            public void test() {
                System.out.println("匿名内部类" + test);
            }
        }.test();
    }
}
public class Text {
    public static void main(String[] args) {
       Outter out = new Outter();
       out.fun(20);
    }
}
输出:匿名内部类 20

7. final 关键字

1. 使用final修饰类、方法、属性。

2. final成员变量必须在声明的时候初始化或者在构造器中初始化,否则会报错。

3. 使用final定义的类不能有子类,

4. final一旦修饰一个类之后,该类的所有方法默认都会加上final 修饰。

5. 使用final 定义的方法不能被子类覆写。

6. 使用final 定义的变量就成为了常量,必须在声明的时候赋值,并且不能被修改

7. 使用final修饰的变量不能再次赋值。

8. 定义常量,常量全部都用大写,多个单词知寄件用‘ _ ’分割。

           public static final int MAX_COUNT = 20;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值