Java——初识面向对象

目录

1.面向对象——能进行现实生活的抽象

2.新兴的编程范式

3.面向对象名字扩展

4.面向对象三大特征

5.类与对象的定义与使用

5.1 对象的产生

5.2 对象内存分析

6.构造方法

7.this关键字

8.private实现封装

9.static关键字

 9.1 static类属性

9.2 static类方法


1.面向对象——能进行现实生活的抽象

世界是由一系列对象互相组合形成(多个对象之间的相互协作),每个对象有自己的属性和方法。

面向对象:即对现实事物进行的抽象,把具有共同特点的东西抽象为一个类

通俗解释:狗吃粮,狗和粮是两个对象 ,吃是行为

每个对象——类,每个类有自己的属性及方法

2.新兴的编程范式

面向切面编程:EE-AOP

面向接口编程——接口优先原则

函数式编程:Scala(JVM)

3.面向对象名字扩展

4.面向对象三大特征

a.封装性:内部操作对外部而言不可见,强调保护性

b.继承性:对现有类在无需重新编写原来的类的情况下,进行功能上的扩展。

c.多态性:一个类实例的相同方法在不同情形下有不同的表现形式。好处:使得具有不同内部结构的对象可以共享相同的外部接口。(利用多态可以得到良好的设计)

5.类与对象的定义与使用

class 类名称 {
    属性1;
    属性2;
    属性n...;
        
    方法1(){}
    方法2(){}
    方法n(){}...
 }
 
  • 是共性的概念;对象是一个具体的、可以使用的事物。
  • 类的组成:

  • 先有类才可以产生对象。对象的所有属性与行为,一定在类中进行了完整定义。
  • 类中的属性与方法(不带static关键字的)只能通过对象调用
  • 类的设计原则:编写类时,没有额外说明,所有属性必须使用private封装(成员变量)
  • 类定义顺序:

定义属性 -> 定义构造方法 -> 定义普通方法

  • 5.1 对象的产生

对象在主方法中产生

  • 产生语法:
类名称 对象名称 = new 类名称
  1. 开辟内存空间
  2. 初始化成员变量
  3. 调用默认构造器
  4. 把堆中的对象赋给栈中的引用
  • 对象(引用数据类型)必须在实例化后调用,否则会产生 NullPointerException (运行时错误),编译时不会出错。

/**
 * 将人抽象为一个类
 * Author: qqy
 */
public class Person {
    //属性
    private String gender;
    private int age;
    private String name;
    private int height;

    public static void main(String[] args) {
        //对象
        Person person=new Person();
        person.gender="女";
        person.age=10;
        person.name="张三";
        person.height=60;
        person.movie();
        person.music();
    }

    //行为
    public static void movie(){
        System.out.println("看电影");
    }

    public static void music(){
        System.out.println("听音乐");
    }

}
  • 5.2 对象内存分析

     先简单的将Java中的内存区域分为栈内存和堆内存两块区域

栈内存(虚拟机局部变量表):存放的是局部变量(各种基本数据类型 / 对象引用-对象名字)

堆内存:保存对象(new表示在堆上新分配空间)

垃圾空间:没有任何栈内存指向的堆内存空间

6.构造方法

  • 抽象出一个类,如果没有明确定义,系统会自动生成无参构造;若在类中自定义了构造方法,则系统不会自动生成无参构造。
  • 默认的构造方法:
public 类名(){
}
  • 意义:类中属性初始化
1Person 2person = 3new 4Person();

1类名:通过哪个类产生对象

2产生的对象名,引用一块堆内存

3开辟一块堆内存

4构造方法

public class Person1{

    String name;
    int age;
    private String secret ="xxxxx";

    //构造方法
    //方法名与类名一样
    //返回值:无
    public Person1(){

    }

    public Person1(String name,int age){
        //我的name等于你给赋值的name
        this.name=name;
        this.age=age;
    }

    String personInfo(){
        return "这个人叫"+name+",年龄"+age;
    }

    String getSecret(){
        return secret +"!!";
    }

    //具体对象
    public static void main(String[] args){

        //对象1
        Person1 person = new Person1();//创建对象
        //对对象的属性进行赋值
        person.name="Jack";
        person.age=21;

        //对象2
        Person1 person1=new Person1("张三",23);

        //引用传递
        //peron对象引用的地址赋值给person2
        Person1 person2 = person;
        person2.age=25;   //person的age也改变

        //person变量引用指向空
        //person = null;
        //person4 = null;

        //堆上的person对象已经没有 变量 使用它(引用)
        //但是person对象依然存在,不做内存回收,JVM自动回收

        //调用对象的行为(方法)
        System.out.println(person.personInfo());
        System.out.println(person1.personInfo());
        System.out.println(person2.personInfo());

        System.out.println(person.getSecret());
    }
}

疑问:

Person person;

Person person=null;

上述两种表达有何不同???

解答:

第一种只是声明,没有初始化,无法通过编译;第二种是将person初始化为null,运行时可能会出现空指针异常。

  • 三大特征:

a.构造方法名称必须与类名称相同

b.构造方法没有返回值类型声明(构造本身有返回值,返回当前构造的对象)

c.每个类中一定至少存在一个构造方法。

  • 属性、构造方法、普通方法

属性是在对象开辟堆内存时开辟的空间

构造方法是在使用new后调用的

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

  • 构造方法重载:参数个数不同,可以创建出不同属性信息的对象
  • 匿名对象:
new Person("张三",20).getPersonInfo();

由于匿名对象不会有任何的栈空间所指向,所以使用一次后就成为垃圾空间。 

7.this关键字

a.表示调用属性

   只要在类中访问类的属性,一定要加上this关键字

b.表示调用本类方法

   (1)调用普通方法   this.方法名(参数)

            当有类的继承关系时,表示本类方法一定要加上this关键字。否则,可加可不加。

   (2)调用构造方法   this(参数)

            this调用构造方法必须放在构造方法首行;this调用构造方法不允许成环,以便留有出口 

c.表示当前对象

   只要对象调用了本类中的方法,这个this就表示当前执行的对象 

   打印对象时,生成的是类的类型+hashcode(java在内部对每一个对象做一个编码,表示其唯一性)

代码示例:

/**
 * this关键字
 * Author:qqy
 */

public class OOP {
    String gender;
    String name;
    int age;

    public void setGender(String gender) {
        this.gender = gender;
    }

    public OOP() {
        System.out.println("无参构造方法");
    }

    public OOP(String name, int age) {
        //this调用本类无参构造
        this();
        //this调用本类属性
        this.name = name;
        this.age = age;
    }

    public OOP(String name,int age,String gender){
        //this调用本类有参构造
        this(name,age);
        this.gender=gender;
        //this调用普通方法
        this.print();
    }

    String personInfo() {
        return "这个人叫" + name + "年龄" + age+"性别"+gender;
    }

    public void print() {
        System.out.println("*****************");
    }

    public void print1() {
        //this表示当前对象
        System.out.println("print   " + this);
    }

    public static void main(String[] args) {

        OOP per1 = new OOP();
        per1.name = "Tom";
        per1.age = 18;

        OOP per2 = new OOP("Mary",25);
        per2.setGender("女");

        OOP per3 = new OOP("Alice", 22,"女");

        System.out.println(per1.personInfo());  //这个人叫Tom年龄18性别null
        System.out.println(per2.personInfo());  //这个人叫Mary年龄20性别女
        System.out.println(per3.personInfo());  //  这个人叫Alice年龄22性别女
        per1.print1();                          //print   com.qqy.oop.OOP@1540e19d
    }
}

8.private实现封装

将属性、方法用private封装后表示,被封装的属性与方法只能在本类中使用,类外部不可见。此时想要访问被封装的属性,必须提供getter和setter方法。

  • setter方法:主要进行属性内容的设置与修改
  • getter方法:主要进行属性内容的取得

  • 当类中有一个属性不希望被外部访问或修改,则不需写setter方法
  • private可以用于内部类的封装,但是不能用于外部类的封装

代码示例:

public class OOP{
	private String name;
	private int age;
	private String secret="***";
	private String hobby;
	
	//假设创建对象时必须同时赋予名字,因此,不提供无参的构造方法
	
	//有参的构造方法
	public OOP(String name){
		this.name=name;		//对象的名字=赋值的名字
	}
	
	//方法、行为
	public String personInfo(){
		return "这个人叫"+name+",年龄是"+age+",爱好是"+hobby;
	}
	
	//getter getXXX()  XXX为属性名称
	String getName(){
		return name;
	}
	
	int getAge(){
		return age;
	}
	
	String getSecret(){
		return secret;
	}
	
	String getHobby(){
		return hobby;
	}
	
	//setter setXXX()  XXX为属性名称
	void setAge(int age){
		this.age=age;
	}
	
	void setHobby(String hobby){
		this.hobby=hobby;
	}
}

public class OOPTest{
	public static void main(String [] args){
		//对象1
		//创建对象
		//假设姓名不得修改,因此不提供setName()方法
		OOP per1=new OOP("Tom");
		
		// 对属性赋值
		per1.setAge(20);
		per1.setHobby("跑步");
		
		//OOP类的保护——封装
		//外部程序要访问 封装的属性 通过提供的getter方法访问
		System.out.println(per1.getSecret());
		System.out.println(per1.personInfo());
	}
}

9.static关键字

  •  9.1 static类属性

static属性又称为类属性(静态属性),保存在全局数据区中(方法区——所有对象共享区域),通过类名直接调用,与对象实例化无关。

代码示例:

/**
 * static属性
 * Author:qqy
 */
public class Test {
    public static void main(String[] args) {
        Person3 p1 = new Person3();
        p1.name = "张三";
        p1.age = 10;
        Person3 p2 = new Person3();
        p2.name = "李四";
        p2.age = 20;
        p1.getPersonInfo();
        p2.getPersonInfo();
    }
}

class Person3 {
    String country = "中国";
    String name;
    int age;

    public void getPersonInfo() {
        System.out.println("姓名:" + this.name + ",年龄:" + this.age + ",国家:" + this.country);
    }
}

内存分析图:

将上述代码改为:

class Person3 {
    //类属性(静态属性)
    static String country = "中国";
    String name;
    int age;

    public void getPersonInfo() {
        System.out.println("姓名:" + this.name + ",年龄:" + this.age + ",国家:" + Person3.country);
    }
}

则内存分析图:

  • static属性(类属性)不受对象实例化控制,而所有的非static属性(实例变量)必须在对象实例化后使用,
  • 定义类时,如何选择实例变量和类属性?

在定义类时,以非static属性(即实例变量)为主;需要描述共享属性的概念,或不受对象实例化控制,使用static

  • 9.2 static类方法

使用static定义的方法,直接通过类名调用。与对象实例化无关,广泛存在于工具类中。

  •     所有的static方法不允许直接调用非static定义的属性或方法,只能 1.在静态方法中new一个对象,通过对象调用  2.给静态方法中的参数传一个对象;

/**
 * 静态调用非静态
 * Author:qqy
 */
public class Test1 {
    static int i;
    int b;

    public static void main(String[] args) {

    }

    public void eat(){
        System.out.println("chi"+i+b);
    }

    //1.
    public static void drink(){
        Test1 t=new Test1();
        t.eat();
        System.out.println("he"+i+t.b);
    }
    
    public static void drink(Test1 t){
        t.eat();
        System.out.println(i+t.b);
    }
}
  • 所有的非static方法允许访问static方法或属性

  •     局部变量不能用static修饰(对于方法中的变量不能用static修饰)

  •     static不能加在外部类之上,内部类可以

  • main( )方法是程序的入口。因为main( ) 方法是静态方法,不受对象的控制,可以被调用,调用的时候不需要面向对象。
  • 调用静态的属性和方法,建议加上类名——    类名. 属性名     类名. 方法名

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值