黑马程序员——Java基础语法 之面向对象(概念,特征,this,static关键字,代码块)

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

面向对象概念

java语言最大特点,面向对象思想
面向过程强调的是实现功能的行为,代表语言有 C语言
例子:开车上班案例
1,打开引擎
2,操纵汽车
3,关闭引擎

而面向对象强调的是具有什么功能,属性的对象
同上案例
1,人上车
2,汽车运动
3,人下车
面向过程以具体动作为主体,而面向过程以执行某功能的对象为主体

面向对象的特点

1,符合人类思考习惯的思想,把复习的问题有逻辑地细化为一个个简单的对象,每个对象简单执行自己的功能
执行转化为指挥。
编程思想
要完成某项需求,先找某样能完成需求的对象来用,没有就创建具有所需功能的对象
有效简化开发,提高复用。
面向对象三大特征:封装,继承,多态
封装表示把功能,属性包起来,成为一个类
继承是指一个类对另一个类进行继承
多态是一个实体的多种形式、允许将子类类型的指针赋值给父类类型的指针。

类与对象的关系:

java中,类是对事物的描述,而不是事物本身。是具体事物的抽象、概念的定义。
对象则是这类事物实实在在存在的个体:
简单来说,类是某样具体事物的设计图,对象就是这件事物。
类定义了这件事物的属性和功能(方法),对象就有了这样的属性和功能。

类的定义:class
类通过定义属性和行为描述事物
属性:类中的成员变量
行为:类中的成员函数

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

成员变量
1成员变量定义在类中,能被整个类中的任何位置访问
2成员变量有些随着对象的建立而建立,随着对象的消失而消失,而有些随着类的加载而加载,如带static修饰的成员变量
3成员变量都系统自带默认初始值
4成员变量储存在堆内存或者方法区内
局部变量
1局部变量定义在局部范围内,只在局部范围内有效,如函数内,代码块内。
2局部变量储存在栈内存中,出了作用范围,占用的内存空间就释放
3局部变量没有系统默认初始化值,所以必须自己初始化

创建对象,使用对象
创建对象前,得先有可以创建对象的类:
例子:

class Student   //定义Student的设计图
{
    private String name;//三个个私有成员变量
    private int age;
    private String school=“西山中学”;
    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 String getSchool(){
        return school;
    }
}
class ClassDemo 
{
    public static void main(String[] args) 
    {
        Student stu =new Student("小王",16);//根据设计图创建实例,通过new表示建立新对象
        System.out.println(stu.getName());//打印通过实例提供的方法返回的值
    }
}

对象在内存中的结构:

跟数组储存在内存中的结构类似

Student stu1=new Student("小王",15);
Student stu2=new Student("小花",16);

这里创建了两个新Student对象,并分别把其引用赋值给stu1和stu2
stu1和stu2分别储存了 对应的储存在堆内存Student对象 的引用地址,并被存放在栈内存中,所以stu1,stu2储存的并非对象的数据,而是对象再堆内存的地址。

stu2=stu1;//表示把stu1的引用赋值给stu2
stu2.setName("小红");,//是在操作Student("小王",15)这个对象

同时原来stu2指向的new Student(“小花”,16)对象由于没有了引用,在不定时之后会被清除,释放内存
这上边涉及基本数据类型作为参数传递和引用数据类型作为参数传递的不同。
在java中,方法参数的传递永远都是传值,而这个值,对于基本数据类型,值就是你赋给变量的那个值。
而对于引用数据类型,这个值是对象的引用,而不是这个对象本身。

匿名对象:

匿名对象是对象的简化形式。
上面创建对象的方式(Student stu1=new Student(“小王”,15);)类似于把新创建出来的Student(“小王”,15)起名为stu1
而匿名对象就是直接使用新对象而不起名。
匿名对象两种使用情况:
1.当对对象方法仅进行一次调用时;
2.匿名对象可以作为实际参数进行传递。

例子:
同样是上面Student类
主函数改为:

class ClassDemo 
{
    public static void main(String[] args) 
    {
        //只调用一次,可以直接使用匿名对象,也可以作为实际参数传递
        System.out.println(new Student("小王",16).getSchool());
        showName(new Student("小花",16));
    }
    public static void showName(Student str)
    {
        System.out.println(str.getName());
    }
}

封装

是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
好处在于
1,将变化隔离。
2,便于使用。
3,提高重用性
4,提高安全性

封装原则

1.将不需要对外提供的内容都隐藏起来。
2.把属性都隐藏,提供公共方法对其访问。如,getXXX,setXXX。
例子:

class Student   //定义Student的设计图
{
    private String name;//三个个私有成员变量
    private int age;
    private String school=“西山中学”;
    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 String getSchool(){
        return school;
    }
}

需要注意的是,
private关键字:是一个权限修饰符,用于修饰成员(成员变量和成员函数),被私有化的成员只在本类中有效。可以避免某些不安全访问。对于必须提供对外访问的属性可以提供set,get方法对其访问,通过条件判定等方式可以提高安全性。

构造函数

类中函数名与类名完全相同的函数
特点:与类名相同
不用定义返回值类型,void都不用
没有具体的返回值
主要作用是给对象进行初始化

class Student   //定义Student的设计图
{
    private String name;//私有成员变量
    Student(String name){//构造函数,函数名与类名相同
        this.name=name;
    }
    public String getName(){//定义三个共有方法,提供给外部访问
        return name;
    }
    public void setName(String name){
        this.name=name;
    }
}

构造函数在创建对象时运行,必然调用并且只调用一次。

Student stu=new Student("小王");//初始化了name=“小王”
System.out.print(stu.getName);//打印结果为  小王

如果定义类时没有自定义构造函数,系统自动加入一个无参数构造函数
如果在类中定义了指定的构造函数,那么类中的默认构造函数就没有了。

class Student   //定义Student的设计图
{
    private String name;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name=name;
    }
}

系统自动添加一个无参数构造函数

Student(){}

所以创建对象应该:

Student stu=new Student();

同时允许多个构造函数同时存在,名字相同,参数不同
多个构造函数是以重载的形式存在的。

class Student   //定义Student的设计图
{
    private String name;//私有成员变量
    private int age;
    Student(String name){//构造函数,函数名与类名相同
        this.name=name;
    }
    Student(int age){//构造函数,函数名与类名相同
        this.age=age;
    }
    public String getName(){//定义三个共有方法,提供给外部访问
        return name;
    }
    public void setName(String name){
        this.name=name;
    }
}

this关键字

this表示函数所属对象的引用,就是本类对象的引用

常见this的使用:
1,成员本类与局部变量重名时,通过关键字来区分。例如“

class Student
{
    private String name;
    public void SetName(String name){
        this.name=name;
    //this.name表示对象的name属性,而后面的name是形式参数的name,意思是把传入的name的值赋给对象的name属性
    }
}

2,在一个类的构造函数中调用其他构造函数时,需要用this语句。
只能定义在构造函数主体中的第一行,因为初始化动作要先执行,否则报错。

class Student
{
    private String name;
    private String school;
    Student(){
        school="西山小学";
    }
    Student(String name){
        this();
        this.name=name;
    }
    public void SetName(String name){
        this.name=name;
    //this.name表示对象的name属性,而后面的name是形式参数的name,意思是把传入的name的值赋给对象的name属性
    }
    public String getSchool(){
        return school;
    }
}

class TestDemo 
{
    public static void main(String[] args) 
    {
        System.out.println(new Student("小花").getSchool());
    }
}

打印结果为

西山小学

static 关键字

static关键字用于修饰成员(包括成员变量和成员函数)
被static修饰的变量和函数具有以下特点
1,随着类的加载而加载,所以先于对象存在
2,储存在方法区而不是对内存中,不需要实现对象便能直接通过类名调用
3,被所有对象所共享,包括非本类对象。
4,被static修饰的函数不能调用非静态(没有被static修饰的)变量或者函数方法,因为静态方法在类装载的时候就分配了内存块,而非静态的方法和变量在new这个类的对象的时候才分配内存块,
他们内存分配的时间不一样 静态区域访问非静态区域是没有任何意义的
5,被static修饰的函数不能使用this关键字,super关键字
6,非静态函数可以调用静态变量或函数

什么是成员变量,静态变量,类变量,实例变量??
成员变量又称实例变量
类变量又称静态变量
他们的区别是:
1,两种变量的生命周期不同
成员变量随着对象的创建而存在,随着对象的收回而消失
类变量随着类的加载而存在,随着类的消失而消失
2,调用方式不同
成员变量必须实现对象,而后通过对象去调用
类变量可以被对象调用,也可以直接被类名调用
3,储存位置不同
成员变量存在于堆内存中
类变量存在于方法区的静态区中,又称共享数据区,所以又叫对象的共享数据

例:

class Student
{
    public String name;
    public static String school="西山小学";
    Student(String name){
        this.name=name;
    }
    public String getName(){
        return name;    
        }
    public String getSchool(){
        return school;
    }
}
class TestDemo 
{
    public static void main(String[] args) 
    {
        Student stu=new Student("小花");
        System.out.println(stu.getName());
        System.out.println(stu.getSchool());
        System.out.println(Student.school);
        //System.out.println(Student.name);//这样引用错误,不注释编译失败
    }
}

静态修饰的作用
1.静态变量
当分析对象中所具备的成员变量的值都是相同时,这时这个成员就可以被静态修饰。
只要数据在对象中都是不同的,就是对象的特有数据,必须存储在对象中,是非静态的。
如果是相同的数据,对象不需要做修改,只需要使用即可,不需要存储在对象中,定义成静态的。
减少堆内存的占用
2.静态函数
函数是否用静态修饰,就参考一点,就是该函数功能是否需要访问到对象中的特有数据。
简单点说,从源代码看,该功能是否需要访问非静态的成员变量,如果需要,该功能就是非静态的。
如果不需要,就可以将该功能定义成静态的。当然,也可以定义成非静态,但是非静态需要被对象调用。
如果没有访问特有数据的方法,该对象的创建是没有意义。
例如某个工具类中的排序方法,不需要特别参数辅助计算,只要传入数组引用,就能运算排序,定义成
静态函数,可以方便使用。

代码块:

静态代码块,构造代码块,局部代码块
静态代码块:

static{
    代码;
}

在类中,函数外,被static修饰的代码块
随着类的加载而执行,而且只执行一次。
作用:用于给类进行初始化。
构造代码块:

{
代码;
}

在类中,函数外,没有任何修饰符的代码块
作用:可以给所有对象进行初始化。
局部代码块

{
代码;
}

在函数中的被{}包围的代码块,限定作用范围
例:

class Student
{
    public String name;
    public static String school="西山小学";
    {//构造代码块
            System.out.println("构造代码块执行");

    }
    static{//静态代码块
        System.out.println("静态代码块执行");
    }

    Student(String name){//构造函数
        this.name=name;
        System.out.println("构造函数执行");
    }
    public String getName(){
        return name;    
        }
    public String getSchool(){
        return school;
    }
}
class TestDemo 
{
    public static void main(String[] args) 
    {
        Student stu=new Student("小花");
        System.out.println(stu.getName());
        {//局部代码块
            int a=3;
                System.out.println(a);
        }
        //System.out.println(a);//这句不注释会编译失败,提示找不到符号,说明变量a的作用域在局部代码块内
    }
}

打印结果:

静态代码块执行
构造代码块执行
构造函数执行
小花
3

由此可知,执行顺序静态代码块先执行(类加载时执行,构造代码块(实现对象时,在构造函数执行前)执行最后到构造函数执行

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值