java 对象浅解

2024-06-18 21:38
文章标签 java 对象 浅解

本文主要是介绍java 对象浅解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

java是一种面向对象的的语言,在Java程序员眼中万物皆对象。而对象就是讲有共同点的事务的共同部分抽离出来,然后定义一个类。而那些共同事务单独进行操作或其他行为就是类的实例。

简单的理解就是现有一个模版或者模子(类),然后通过这个模板而进行创建一个对象。狗就是一个模板,尤其常有的特征毛发,腿,鼻子等属性,而其还有一些行为比如跑,叫等(对象称之为方法)。 而泰迪就是一个对象了,它必然也会有毛发,腿,鼻子,也可以跑,叫等。但是其又有自己独特的地方,比如毛发长短,颜色,以及腿鼻子的形状等特征,跑的姿势以及叫的声音。

对象其有三个主要特征:封装,继承,多态。

  • 封装:增强安全性和简化编程,使用者不必了解具体的实现细节,而只要通过对外公开的访问方法,来使用类的成员。

  • 继承:可以理解为,在一个现有类的基础之上,增加新的方法或已有方法,从而产生一个新类。

  • 多态:相同的事物,调用其相同的方法,参数也相同时,但表现的行为却不同。

先不进行各自详细解析,因为三个特征也是总结出来的,而其完全的可以先放在一起理解一下。

何为封装,封装就是将其类必须拥有的特征封装起来也就是这个类必须拥有的特点,比如狗这个类,它的一些特点,你无法套用在鱼上。 这个时候我们在创建类的时候,肯定有人说了狗吃东西,鱼也吃东西呀,难道这个吃就不可以封装到类中?当然也可以,因为java中所有的类都继承object这个类,也就是后面所说的继承,而鱼和狗难道都不是生物吗?自然也就继承了生物的一些特种,这个就是所谓的继承。你看见泰迪你可以说时狗,你看见狼狗也可以说是狗。而两个都可以吃,狼狗在吃肉,泰迪在吃罐头,都是狗的吃的行为,但是我们指着泰迪说,这狗吃东西呢,就是说狗吃罐头。我们用狗来泛指,但是我们知道他是指泰迪,而它的吃的行为就是吃罐头。

 狗类  狗=泰迪类 泰迪()狗.吃的行为()最后得到狗(泰迪)吃罐头。

多态也有其必要条件:

  • 前提:必须继承,如果没有继承也就没有多态的可能

  • 实现:子类必须重写父类的方法,因而才会有多态的效果

  • 表现形式:等号左侧必须时父类,而右侧new的部分时子类。这个是多态的表现形式。

// 此为父类
public class Father{//方法
}public class Son extends Father{//方法   
}

构造方法

既然时面向对象,那么就应该知道构造方法,什么时构造方法呢?

构造方法是一种特殊的方法,它是一个与类同名的方法。对象的创建就是通过构造方法来完成,其功能主要是完成对象的初始化

public class Son {
public Son() {// TODO Auto-generated constructor stub
}
}

默认无参的构造函数,是可以不用写出的,所以一般我们是用的时候之间new Son(),直接就可以调用。

  • 注意:如果没有其他有参的构造函数,那么要使用的时候无参构造函数可以不写,但是如果有了有参构造函数还要使用无参构造函数,那么无参构造函数必须写出。

    //如果不需要无参构造函数,那么不写无参函数如下
    public class Son {
    public Son(int age) {// TODO Auto-generated constructor stub
    }}//如果需要无参构造函数,那么需要写无参函数如下
    public class Son {
    public Son() {// TODO Auto-generated constructor stub
    }
    public Son(int age) {// TODO Auto-generated constructor stub
    } 
    }

    如果上面,第一个直接new的时候需要new Son(5),但是如果还需要无参构造函数 new Son()就会报错,需要第二种写法了,可以理解成为一个重载构造方法

    而在

首先我们看一下在创建子类对象,会发生什么事情,如下:

//父类public class Father {public father() {System.out.println("father");}
}//子类
public class Son extends Father{public Son() {System.out.println("son");}}//测试类
public class Test{public static void main(String[] args) {Son s=new Son();}}//输出的结果
father
son

由此可以看出,在创建子类的时候父类也会自动实例一个对象。

先不解释为什么会这样,我们首先要知道两个关键字 super和this

//父类
public class Father {int age=55;
}
//子类
public class Son extends Father{int age=15;public void out(int age) {System.out.println(age);System.out.println(this.age);System.out.println(super.age);	}
}//测试类
public class Test{public static void main(String[] args) {Son s=new Son();s.out(10);}}
//输出结果
10
15
55

this:字面意思,就是指当前类,而this+.+(方法或属性)就是指当前方法的属性或者方法。

但在使用过程中需要我们注意:

  • 每个类的每个非静态方法(没有被static修饰)都会隐含一个this关键字,它指向调用这个方法的对象;当在方法中使用本类属性时,都会隐含地使用this关键字,当然也可以明确使用。

  • this关键字只能在方法内部使用,表示对“调用方法的那个对象”的引用如果是在同一类中调用另外一个方法,则可以不用写this,直接调用

    也就是this就是值当前对象,但是为什么会注明一点过要在非静态方法中使用呢?

    看一下代码:

    //父类
    public class Father {static{	System.out.println("father的static模块");	}{System.out.println("father的模块");	}public Father() {System.out.println("father");}
    }
    //子类
    public class Son extends Father{public Son() {System.out.println("son");}{System.out.println("son的模块");	}static{System.out.println("son的static模块");	}
    }//测试类
    public class Test{public static void main(String[] args) {Son s=new Son();Son s2=new Son();}}//输出结果
    father的static模块
    son的static模块
    father的模块
    father
    son的模块
    son
    father的模块
    father
    son的模块
    son

简单的陈述就是看出实例化一个对象 :

		第一步:父类执行了static 模块第二步:子类执行了static 模块第三步:父类执行了 模块,第四步:父类执行了构造方法第五步:子类执行了 模块,第六步:子类执行了构造方法第七步:父类执行了 模块第三步到第七步又执行了一边

我们可以看出static 模块和普通模块执行优先鱼构造方法,同时虽然生成了两次对象,但是static只是执行了一次。还有static的方法也会优先与实例化(new一个对象)而执行。所以无法在static方法中使用this,因为当时没有一个对象,所以会报错。

  • this关键字的用法

    • 当类中非静态方法的参数名与类的某个成员变量名相同时,为了避免参数作用范围覆盖了成员变量的作用范围,必须明确使用this关键字来指定

      而这种通常体现在对象的属性中的get和set方法中,下面属性中会呈现。

    • 如果某个构造方法的第一条语句具有形式this(…),那么这个构造方法将调用本类中的其他构造方法。简单的理解上面所说的构造方法的重载,可以之间通过this来相互调用。

    • 如果某个方法需要传入当前对象,则可以将当前的对象作为参数传递给它。这个很简单理解,毕竟this就是指本身对象。

super:super代表了父类空间的引用

  • super的作用:

    • 子父类存在着同名的成员时,在子类中默认时访问子类的成员,可以通过super关键字指定访问父类的成员

    • 创建子类对象时,默认会先调用父类无参的构造方法,可以通过super关键字指定调用父类的构造方法

      这个就是要说的,就是子类的构造方法中默认有一个super(),如果要写的话,一定要写在子类构造函数的第一行,不然会被报错。

  • super的方法

    super可以用来引用直接父类的实例变量。

      super可以用来调用直接父类方法。super()可以用于调用直接父类构造函数
    

    简单总结一下this与super的区别:

        super必须是有继承才可以使用,不然没有父类,也就没有所谓的super使用,而this本身就是自身,所以没有这个限制
    

属性

既然是对象,那就有其自身的特征,但是在java 中称之为属性。

public class Son {int age;String name;}

属性一般都是private 类型,也就是私有。因为程序也会默认private,所以一般需要写出表明,从侧面也表现出对象的封装.而属性都有其默认值,比如int类属性默认是0;

这样做的好处,就是防止对象以为对属性的调用,保证对象的安全。因为是私有的,所以对对象属性的操作我们就需要get和set方法了。

public class Son {int age;String name;//得到age的值public int getAge() {return age;}//赋予age的值public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

在外可以通过son s=new son(),然后通过s,对属性进行赋值或得到属性的值。

类属性:作为补充,还有一个属性,那就是类属性。对于类属性的判断依据就是有static符修饰的属性。可以称之为类属性,可以知道通过对象类进行调用,而可以直接通过类名进行调用,当然你new一个对象也可以调用。如下

public class Son {static int age;}public class Test{public static void main(String[] args) {System.out.println(Son.age);Son s=new Son();System.out.println(s.age);}
}
//最后打印出为0(因为没有赋值,得到默认值0,当然也可以直接赋值)
输入的结果是:
0
0

类属性的值,是一个共享的值。也就是如果值进行了改变,无论通过类名进行修改或者new的对象进行修改,对于调用这个类属性都会改变。

可以同一下程序理解一下:

public class Son {static int age;}public class Test{public static void main(String[] args) {System.out.println(Son.age);//输出的值0Son s=new Son();System.out.println(s.age);//输出的值0// 这个是通过类名对类属性值修改       Son.age=7;Son s1=new Son();System.out.println(s1.age);//输出的值7// 这个是新new的一个对象对类属性值修改       s1.age=9;System.out.println(s.age);//输出的值9}
}

属性尤其自己的独特优势,因为java时值传递,也就是在调用方法的时候,可以理解为进行的一个副本传递过去,而本身不会发生变化。

public class Test{public static void main(String[] args) {int a=10;out(a);System.out.println(a);}public static void out(int a) {a=a+10;System.out.println(a);}
}
//输出结果
20
10

可以看出java在传递的时候只是数值的传递,而其修改后对于原来的数据没有影响。而对象的调用却不是这样,这个涉及到另一个那就值传递和引用传递的解释,此处我们单独讲解java对象,暂时不过多陈述,后面单独会出一篇文章。

public class Son extends Father{int age;public int getAge() {return age;
}public void setAge(int age) {this.age = age;
}  
}public class Test{public static void main(String[] args) {Son s=new Son();
//	 可以通过set方法赋值s.setAge(10);
//	 通过个体方法得到值System.out.println(s.getAge());updata( s);System.out.println(s.getAge());}public static void updata(Son s) {s.setAge(20);}	
}

多态:

多态也有其必要条件,上面我写过,现在重新在写一遍:

  • 前提:必须继承,如果没有继承也就没有多态的可能

  • 实现:子类必须重写父类的方法,因而才会有多态的效果

  • 表现形式:等号左侧必须时父类,而右侧new的部分时子类。这个是多态的表现形式。

    下面我会用代码演示一遍,父类用dog,如果还用father和son的话估计会有点绕不过弯,

    public class Dog {public void eat() {System.out.println("狗在食物");}}
    //第一个子类
    public class TaiDi extends Dog{public void eat() {System.out.println("泰迪在吃罐头");}}//第二个子类
    public class LangGou extends Father {public void eat() {System.out.println("狼狗在吃肉");}
    }
    //测试类
    public class Test{public static void main(String[] args) {Dog td=new TaiDi();td.eat();Dog lg= new LangGou();lg.eat();}
    }
    //输出
    泰迪在吃罐头
    狼狗在吃肉

    因为子类如果有方法直接运行子类的,就不会运行父类被重新的方法。

    有人就好奇问,第一和第三点可以理解,但是为什么子类必须重新父类的方法,因为左侧为父类对象,如果子类不重新,一般子类无方法会调用父类,也就是说何来多态。

    public class Dog {public void eat() {System.out.println("狗在食物");}}
    //第一个子类
    public class TaiDi extends Dog{}//第二个子类
    public class LangGou extends Father {}
    //测试类
    public class Test{public static void main(String[] args) {Dog td=new TaiDi();td.eat();Dog lg= new LangGou();lg.eat();}
    }
    //输出
    狗在食物
    狗在食物

    如果有人脑洞大开说,那我父类没有被重写方法咋样?

    public class Dog {}
    //第一个子类
    public class TaiDi extends Dog{public void eat() {System.out.println("泰迪在吃罐头");}}//第二个子类
    public class LangGou extends Father {public void eat() {System.out.println("狼狗在吃肉");}
    }
    //测试类
    public class Test{public static void main(String[] args) {Dog td=new TaiDi();td.eat();//编译不过去,会报错提示没有eat方法Dog lg= new LangGou();lg.eat();//编译不过去,会报错提示没有eat方法}
    }
    

    有人说那我直接将上面的dog 换程taidi和langgou不就可以输出了吗?

    对,是可以输出了,不过那我们直接干嘛还用继承呀 ,直接单独写不就可以了,也不用聊多态了。

补充

上面我们使用了static修饰的属性,称之为类属性,那么我们自然也可以相想到static 修饰的方法了。也可以称之为类方法,它可以继承以及可以实现多态吗?

我们先用代码解释

public class Dog {public void eat() {System.out.println("狗在食物");}public static void run() {System.out.println("狗在跑步");}}
//第一个子类
public class TaiDi extends Dog{public void eat() {System.out.println("泰迪在吃罐头");}public static void run() {System.out.println("泰迪在跑步");}}//第二个子类
public class LangGou extends Father {public void eat() {System.out.println("狼狗在吃肉");}public static void run() {System.out.println("狼狗在跑步");}
}
//测试类
public class Test{public static void main(String[] args) {Dog td=new TaiDi();td.eat();td.run()Dog lg= new LangGou();lg.eat();lg.run()}
}
//输出结果
泰迪在吃罐头
狗在跑步
狼狗在吃肉
狗在跑步

注意:对于静态方法,完全没有继承的样子,因为静态方法和方法类有关,而对象没有关系,是在new对象之前人家就存在了,也就无法实现多态了,所以记住对于继承的时候方法类一般无法不要使用static修饰,因为那样无法被重写也无法实现多态。

这篇关于java 对象浅解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1073123

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

Java五子棋之坐标校正

上篇针对了Java项目中的解构思维,在这篇内容中我们不妨从整体项目中拆解拿出一个非常重要的五子棋逻辑实现:坐标校正,我们如何使漫无目的鼠标点击变得有序化和可控化呢? 目录 一、从鼠标监听到获取坐标 1.MouseListener和MouseAdapter 2.mousePressed方法 二、坐标校正的具体实现方法 1.关于fillOval方法 2.坐标获取 3.坐标转换 4.坐

Spring Cloud:构建分布式系统的利器

引言 在当今的云计算和微服务架构时代,构建高效、可靠的分布式系统成为软件开发的重要任务。Spring Cloud 提供了一套完整的解决方案,帮助开发者快速构建分布式系统中的一些常见模式(例如配置管理、服务发现、断路器等)。本文将探讨 Spring Cloud 的定义、核心组件、应用场景以及未来的发展趋势。 什么是 Spring Cloud Spring Cloud 是一个基于 Spring

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

java8的新特性之一(Java Lambda表达式)

1:Java8的新特性 Lambda 表达式: 允许以更简洁的方式表示匿名函数(或称为闭包)。可以将Lambda表达式作为参数传递给方法或赋值给函数式接口类型的变量。 Stream API: 提供了一种处理集合数据的流式处理方式,支持函数式编程风格。 允许以声明性方式处理数据集合(如List、Set等)。提供了一系列操作,如map、filter、reduce等,以支持复杂的查询和转

Java面试八股之怎么通过Java程序判断JVM是32位还是64位

怎么通过Java程序判断JVM是32位还是64位 可以通过Java程序内部检查系统属性来判断当前运行的JVM是32位还是64位。以下是一个简单的方法: public class JvmBitCheck {public static void main(String[] args) {String arch = System.getProperty("os.arch");String dataM

详细分析Springmvc中的@ModelAttribute基本知识(附Demo)

目录 前言1. 注解用法1.1 方法参数1.2 方法1.3 类 2. 注解场景2.1 表单参数2.2 AJAX请求2.3 文件上传 3. 实战4. 总结 前言 将请求参数绑定到模型对象上,或者在请求处理之前添加模型属性 可以在方法参数、方法或者类上使用 一般适用这几种场景: 表单处理:通过 @ModelAttribute 将表单数据绑定到模型对象上预处理逻辑:在请求处理之前

eclipse运行springboot项目,找不到主类

解决办法尝试了很多种,下载sts压缩包行不通。最后解决办法如图: help--->Eclipse Marketplace--->Popular--->找到Spring Tools 3---->Installed。

JAVA读取MongoDB中的二进制图片并显示在页面上

1:Jsp页面: <td><img src="${ctx}/mongoImg/show"></td> 2:xml配置: <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001

Java面试题:通过实例说明内连接、左外连接和右外连接的区别

在 SQL 中,连接(JOIN)用于在多个表之间组合行。最常用的连接类型是内连接(INNER JOIN)、左外连接(LEFT OUTER JOIN)和右外连接(RIGHT OUTER JOIN)。它们的主要区别在于它们如何处理表之间的匹配和不匹配行。下面是每种连接的详细说明和示例。 表示例 假设有两个表:Customers 和 Orders。 Customers CustomerIDCus