java面向对象


对象

对象的使用

创建对象

格式:类名 对象名 = new 类名();

范例:student s = new student();

使用对象

  1. 使用成员变量

    1. 格式:对象名.变量名
    2. 范例s.age
  2. 使用成员变量

    1. 格式:对象名.方法名()
    2. 范例:s.name();

static

static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途

案例

创建Student 对象

1
2
3
4
5
6
7
8
9
10
11
12
package studentdome;

public class Student {
String name;
int age;
public void study(){
System.out.println("天天学习");
}
public void sum(){
System.out.println("多晒晒太阳");
}
}

调用 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
package studentdome;

public class StudentDome {
public static void main(String[] args) {
Student s = new Student();
s.age = 19;
s.name = "ffy";

System.out.println(s.age +" "+s.name);
s.study();
s.sum();
}
}

对象的内存图

对个对象指向相同的对象

如下:new 一个新的对象名字为s1

用s2 也指向s1

最后地址相同s2直接对s1修改

最后输出结果相同

  1. 创建一个对象先加载打栈内存
  2. new的 对象和变量到堆内存
  3. 调用 s1先指向栈内存 在指向堆内存
  4. 单个内存 和多内存一样 和上面不同
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package studentdome;
//对象Student在上面
public class Studentlost {
public static void main(String[] args) {
Student s1 =new Student();
s1.name = "樊帅营";
s1.age =20;
System.out.println(s1.name+" ,"+s1.age);
Student s2 = s1;
s1.name = "小帅";
s1.age =16;
System.out.println(s1.name+" ,"+s1.age);
System.out.println(s2.name+" ,"+s2.age);

}
}
最后输出的结果为:
樊帅营 ,20
小帅 ,16
小帅 ,16

成员变量和局部变量的区别

区别 成员变量 局部变量
类中位置不同 类中之外 方法或者方法声明上
内存中不同 堆内存中 栈内存
生命周期不同 随着对象存在而存在随着对象消失而消失 随着方法调用而存在随着方法调用完毕而消失
初始化值不同 有默认的初始化值 没有默认的初始化值必须定义完,赋值才能使用

封装

封装简介

  1. 封装的概述

    1. 是面向对象三大特征之一(封装,继承,多态)

    2. 是面向对象编程语言对客观世界模拟,客观世界里的成员变量都是隐藏在对象内部的外部是无法直接操作的

  2. 封装的原则

    将类中的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该提供的方法来实现对隐藏信息的操作和访问成员变量private, 提供对应的get/set 方法

  3. 封装的好处

    通过方法来操控成员变量的操作,提高代码的安全性

    把代码进行封装,提高了代码的复用性

关键词 private

  1. 利用set 来更改私有变量

  2. 利用get 来得到私有变量

  3. 利用set方法给私有变量赋值

  4. 最有get出结果

    PStudent对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package studentdome;

public class PStudent {
//有默认初始值
//全局变量有默认初始值
private String name;
private int age;
public void setAge(int a){
//如果年龄没有负数,可以写一个判断来返回年龄
age = a;
}
//私有变量 利用get 和set 方法可以更改
//也可以在方法中写判断
public int getAge(){
return age;
}
public void setName(String a){
name = a;
}
//注意定义类型要与返回类型相同
public String getName(){
return name;
}
public void show(){
System.out.println(name+","+age);
}
}

main调用对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package studentdome;

public class privatestudent {
public static void main(String[] args) {
PStudent s =new PStudent();
s.setName("樊帅营");
s.setAge(19);
s.show();
//利用get方法更改格式 就是把show 中打印出的,改成其他格式
System.out.println(s.getName()+" "+s.getAge());//一般测试的时候一种格式就够了
}
}
结果:
樊帅营,19
樊帅营 19

get/set固定格式

1
2
3
4
5
6
7
8
9
10
11
12
private 定义类型 名字1; 
get后和set后首字母要大写
public void set名字1(定义类型 名字2){
名字1 = 名字2
}
public 定义类型 get名字1(){
return 名字1;
}
//调用
//用set给名字1赋值
对象名字.set名字1(赋值)
获得结果 对象名字.get名字1()

this关键字

  1. this修饰的变量用于指代成员变量(全局变量 叫法不同)

    1. 方法的修饰如果变量名相同,不带this修饰的变量指的是形参,而不是成员变量
    2. 方法的形参没有与成员变量名字相同,不带this修饰的变量指的是成员变量
  2. 什么时候使用this 呢? 解决局部变量隐藏成员变量

    1. this代表所在类的对象的引用
      1. 记住:方法被那个对象调用,this就代表那个对象

构造方法

  1. 构造方法的概述

  2. 构造方法是一种特殊的方法

  3. 作用创建对象

  4. 格式:

    1
    2
    3
    4
    public class 类名{
    修饰符 类名(参数){
    }
    }
    1
    2
    3
    4
    5
    6
    public class Student{
    public Student() {
    //构造方法内书写的内容
    //这个是无参构造
    }
    }
    1. 构造方法当建立对象的时候直接就调用构造方法

构造方法的注意事项

  1. 构造方法的创建

    • 如果没有定义构造方法,系统默认将给出一个默认的无参构造方法
    • 如果定义了构造方法,系统将不在提供默认的构造方法
  2. 构造方法的重载

    • 如果自定义了带参构造方法,还要使用无参构造方法,就必须写一个无参构造方法
  3. 推荐的使用方法

  • 无论是否使用,都手工书写无参构造方法.

标准类的制作

标准类的制作有两种方法

  1. 无参构造 后用set 方法给对象赋值 最后并调用
  2. 有参构造 ,并在创建对象后面括号里面赋值 并调用
1
2
3
4
5
6
7
8
9
10
11
12
13
package SStudent;

public class StudentDome {
public static void main(String[] args) {
SStudent s = new SStudent();
s.setAge(19);
s.setName("樊帅营");
s.show();
SStudent s1 = new SStudent("樊帅营", 18);
s1.show();
}
}

  1. 调用的对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    package SStudent;

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

    }
    public void setName(String name) {
    this.name = name;
    }
    public String getName(){
    return name;
    }
    public void setAge(int age){
    this.age = age;
    }
    public int getAge(){
    return age;
    }
    public void show(){
    System.out.println(name +","+age);
    }
    }

继承

继承的概述

  • 继承是面向对象的三大特征之一,可以使得子类具有父类的属性和方法,追加属性和方法

继承的格式

  • ~~~java
    格式:
    public class 子类名 extends 父类名{}
    范例:
    public class zi extends fu{}

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54

    - fu 是父类 ,也称为 基类 和超类

    - zi 是子类,也可称为派生类

    继承中子类的特点:

    - 子类可以有父类的内容
    - 子类也可有自己特有的内容

    ### 继承的利和弊

    #### 继承的好处

    - 提高了代码的复用性(多个相同的成员可以放到同一个类中)
    - 提高了代码的维护行(如果方法的代码需要修改,修改一处即可)

    #### 继承的弊端

    继承让类与类产生了关系,类的耦合性增强,当父类发生变化时子类实现不得不跟着变化,削弱了子类的独立性

    #### 什么时候使用继承?

    - 继承的关系 is a
    - 假设法 如果有两个类A和B ,如果他们满足A是B 的一种,或者B是A 的一种,就说明他们有继承的关系,这个时候就可以考虑使用继承来体现,否则就不能滥用继承。
    - 举例 苹果和水果 满足条件 可以使用
    - 猫和动物 满足条件 可以使用
    - 猫和狗 猫不是狗的一种 狗不是猫的一种所以满足条件 不满足不可以使用

    ### 继承中变量访问特点

    #### 在子类方法中访问一个变量时

    - 首先在子类局部范围内找

    - 如果没有 在子类 成员范围内找

    - 如果也没有 去 父类范围找

    - 如果都没有 就会报错(不考虑父亲的父亲.......)

    #### 演示

    测试类

    ~~~ java
    package Dome01;

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

    子类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    package Dome01;

    public class Zi extends Fu{
    public String name=" 张三";
    public int age = 100;
    public void show(){
    int age = 10;
    System.out.println(name);
    System.out.println(age);
    }
    }

    父类

    1
    2
    3
    4
    5
    package Dome01;

    public class Fu {
    public int age = 1000;
    }

    结果

    1
    2
    张三
    10

super

super 的关键字的用法和this的关键字的用法相似

当都有一个相同的变量时候:

  • this:代表本类对象的引用
  • super:代表父类储存空间的标识(可以理解为父类对象的引用)
关键字 访问成员变量 访问构造方法 访问成员方法
this this.成员变量
访问本类成员变量
this(…)
访问本类构造方法
this.成员方法(…)
访问本类成员方法
super super.成员变量
访问父类成员变量
super(…)
访问父类构造方法
super.成员方法(…)
访问父类成员方法

演示

测试类

1
2
3
4
5
6
7
8
package Dome01;

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

子类

1
2
3
4
5
6
7
8
9
10
11
12
13
package Dome01;

public class Zi extends Fu{
public String name=" 张三";
public int age = 100;
public void show(){
int age = 10;
System.out.println(name);
System.out.println(age);
System.out.println(this.age);
System.out.println(super.age);
}
}

父类

1
2
3
4
5
package Dome01;

public class Fu {
public int age = 1000;
}

结果

1
2
3
4
 张三
10
100
1000

继承中构造方法的访问特点

子类中所有的构造方法默认都会方法父类中的无参构造方法

为什么?

  • 因为子类会继承父类中的数据,可能还会使用父类的数据,所以,子类初始化前,一定要先完成父类数据的初始化

  • 每个子类中的构造方法的第一条语句默认都是:super()

  • 演示

  • package Dome01;
    
    public class Dome01 {
        public static void main(String[] args) {
            Zi s = new Zi();
    
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    子类

    - ~~~ java
    package Dome01;

    public class Zi extends Fu {
    public Zi() {
    System.out.println("无参构造被调用");
    }

    public Zi(int age) {
    System.out.println("有参构造被调用");
    }
    }
  • 父类

  • ~~~ java
    package Dome01;

    public class Fu {
    public Fu(){
    System.out.println(“无参构造被调用”);
    }
    public Fu(int age){
    System.out.println(“有参构造被调用”);
    }
    }

    1
    2
    3
    4
    5
    6

    - 结果

    - ~~~text
    无参构造被调用
    无参构造被调用

如果父类中没有无参构造方法,只有带参构造方法怎么办?

  • 通过使用super关键字区县市调用父类的代餐构造方法

  • 在父类中自己提供一个无参构造方法

  • 推荐:自己给出无参构造方法

  • 演示

  • package Dome01;
    
    public class Dome01 {
        public static void main(String[] args) {
            Zi s = new Zi();
            Zi s2 = new Zi(40);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15

    子类

    - ~~~ java
    package Dome01;

    public class Zi extends Fu {
    public Zi() {
    System.out.println("无参构造被调用");
    }

    public Zi(int age) {
    System.out.println("有参构造被调用");
    }
    }
  • 父类

  • package Dome01;
    
    public class Fu {
        public Fu(int age){
            System.out.println("有参构造被调用");
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
      
    - 结果

    - ~~~text
    有参构造被调用
    无参构造被调用
    有参构造被调用
    有参构造被调用
  • 当父类中有无参构造并且不用super时 一直被调用的是父类中无参构造

方法重写

  • 方法重写概述

    • 子类中出现和父类中一模一样的方法声明
  • 方法重写应用

    • 当子类需要父类的功能,而功能主体子类有自截特有内容时,可以重写父类中的方法,这样,即沿袭了父类的功能,又定义 了子类特有的内容
    • 练习:手机和新手机

@Override

  • 是一个注释
  • 可以帮助我们检查重写的方法重写是否正确

演示

  • 子类中

  • package Dome02;
    
    public class Zi02 extends Fu02 {
        @Override
        public void call(String name) {
            System.out.println("开启视频通话");
                super.call(name);
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    - 父类

    - ~~~java
    package Dome02;

    public class Fu02 {
    /*
    手机
    */
    public void call(String name) {
    System.out.println("给" + name + "打电话");
    }}

  • 测试类

  • ~~~java
    package Dome02;

    public class Dome02 {
    public static void main(String[] args) {
    Zi02 z = new Zi02() ;

    z.call(“shua”);
    }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

    ### 方法重写注意事项

    - 私有方法不能被重写(父类私有成员子类是不能继承的)

    - 子类方法访问权限不能比父类低(public>默认>私有)

    - 默认的不用写

    - 例如

    - ~~~java
    package Dome02;

    public class Fu02 {
    /*
    手机
    */
    void call(String name) {
    System.out.println("给" + name + "打电话");
    }}
    • ~~~java
      package Dome02;

      public class Zi02 extends Fu02 {
      @Override
      public void call(String name) {
      System.out.println(“开启视频通话”);
      super.call(name);
      }
      }

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36



      ### java找那个继承的注意事项

      - java中只支持单继承,不支持多继承 (例如:儿子只能继承妈妈和爸爸其中的一种,不能同时继承)
      - java中类支持多层继承(例如:儿子可以继承爸爸,爸爸可以继承爷爷)

      ### 利用继承简化代码

      #### 快捷键

      alt +ins 快捷生成方法

      演示类

      ~~~java
      package Student;

      public class peopleDome {
      public static void main(String[] args) {
      Student s = new Student();
      s.setAge(19);
      s.setName("帅");
      System.out.println(s.getName()+","+s.getAge());
      s.st();
      Student s2 = new Student("shuai",18);
      System.out.println(s.getName()+","+s.getAge());
      s.st();
      teacher t = new teacher();
      t.setName("老师");
      t.setAge(19);
      System.out.println(s.getName()+","+s.getAge());
      t.t();
      }
      }

teacher类

1
2
3
4
5
6
7
8
9
10
11
12
package Student;

public class teacher extends people{
public teacher(){};

public teacher(String name,int age){
super(name,age);
}
public void t(){
System.out.println("教书育人");
}
}

Student类

1
2
3
4
5
6
7
8
9
10
11
12
package Student;

public class Student extends people{
public Student() {
}
public Student(String name,int age){
super(name,age);
}
public void st(){
System.out.println("成就未来");
}
}

继承类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
package Student;

public class people {
private String name;
private int age;

public people() {
}

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

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

结果

1
2
3
4
5
6
帅,19
成就未来
帅,19
成就未来
帅,19
教书育人

多态

多态概述

  1. 同一个对象,在不同时刻表现出来不同形态

  2. 举例:

      • 我们可以说猫是猫:猫 cat = new 猫();
      • 我们也可以说猫是动物:动物 animal =new 猫();
      • 这里猫在不同时刻表现出来的不同形态,这就是多态
    • 多态前提和体现
      • 有继承/实现关系
      • 有方法重写
      • 有父类引用指向子类对象
  3. Dome

    1
    2
    3
    4
    5
    6
    7
    8
    package 多态;

    public class catDome {
    public static void main(String[] args) {
    annals c = new cat();
    c.eat();
    }
    }

    cat

    1
    2
    3
    4
    5
    6
    7
    8
    package 多态;

    public class cat extends annals{
    @Override
    public void eat() {
    System.out.println("猫吃鱼");
    }
    }

    annals

    1
    2
    3
    4
    5
    6
    7
    package 多态;

    public class annals {
    public void eat(){
    System.out.println("吃");
    }
    }

    结果

    1
    猫吃鱼

多态中成员访问的特点

  • 成员变量:编译看左边,执行看左边
  • 成员方法:编译看左边,执行看右边
  • annals(左边) cat= new cat(右边)();

为什么成员方法和成员变量的访问不一样呢?

  • 因为成员方法有重写,而成员变量没有

Dome

1
2
3
4
5
6
7
8
9
10
package 多态;

public class catDome {
public static void main(String[] args) {
annals c = new cat();
c.eat();
System.out.println(c.name);
}
}

cat

1
2
3
4
5
6
7
8
9
10
package 多态;

public class cat extends annals{
public String name = "xiaohuang";
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}

annals

1
2
3
4
5
6
7
8
9
package 多态;

public class annals {
public String name = "xiaobai";
public void eat(){
System.out.println("吃");
}
}

结果

1
2
猫吃鱼
xiaobai

多态的好处和弊端

  • 多态的好处:提高 程序的扩展性

    • 具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作
  • 多态的弊端:不能使用子类特有的功能

演示:

1
2
3
4
5
6
7
8
9
10
11
package 多态;

public class catDome {
public static void main(String[] args) {
annalsObject an =new annalsObject();
cat c = new cat();
an.user(c);
Dog d = new Dog();
an.user(d);
}
}

Dog类

1
2
3
4
5
6
7
8
package 多态;

public class Dog extends annals {
@Override
public void eat() {
System.out.println("狗吃骨头");
}
}

cat类

1
2
3
4
5
6
7
8
9
package 多态;

public class cat extends annals{
public String name = "xiaohuang";
@Override
public void eat() {
System.out.println("猫吃鱼");
}
}

object类

1
2
3
4
5
6
7
8
package 多态;

public class annalsObject {

public void user(annals a){
a.eat();
}
}

annals类

1
2
3
4
5
6
7
8
package 多态;

public class annals {
public String name = "xiaobai";
public void eat(){
System.out.println("吃");
}
}

多态中的转型

  1. 向上转型

    • 从子到父转型
    • 父类引用指向子类对象
  2. 向下转型

    • 从父到子
    • 父类引用转为子类对象

Dome:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package 多态;

public class catDome {
public static void main(String[] args) {
// 向上转型
annals a = new cat();
a.eat();
// 向下转型
cat c = (cat)a;
c.name();
c.eat();

}
}

annals类

1
2
3
4
5
6
7
8
package 多态;

public class annals {
public String name = "xiaobai";
public void eat(){
System.out.println("吃");
}
}

cat类

1
2
3
4
5
6
7
8
9
10
11
12
package 多态;

public class cat extends annals{
public String name = "xiaohuang";
@Override
public void eat() {
System.out.println("猫吃鱼");
}
public void name(){
System.out.println("Tom");
}
}

文章作者: 樊帅营
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 樊帅营 !
评论
评论
  目录