🎉🎉🎉写在前面:
博主主页:🌹🌹🌹戳一戳,欢迎大佬指点!
博主秋秋:QQ:1477649017 欢迎志同道合的朋友一起加油喔💪
目标梦想:进大厂,立志成为一个牛掰的Java程序猿,虽然现在还是一个小菜鸟嘿嘿
-----------------------------谢谢你这么帅气美丽还给我点赞!比个心-----------------------------
类与对象
🌈一,初始面向对象
🌟1.1,什么是面向对象
Java是一门纯面向对象的语言(Object Oriented Program,继承OOP),在面向对象的世界里,一切皆为对象。面向对象是解决问题的一种思想,主要依靠对象之间的交互完成一件事情。
🚩注意:面向对象语言统称为OOP,那么OOP语言的三大特性就是 封装 ,继承,多态,这个得知道,别到时候面试官问你OOP语言的特点,你说你没学过OOP语言那就尴尬了…
🌟1.2,浅浅谈谈面向过程与面向对象的差异
这里用一个例子来给大家讲讲,不然有点抽象,这个例子就是把大象放进冰箱的问题:
🌖1,从面向过程的角度:这很简单,不就是先打开冰箱,然后把大象塞进去,然后关上门,一套操作行云流水,简直帅的不得了。可以看到,对于实现一件事,面向过程它的关注点在于每一步你是怎么操作的,注重的是过程。
🌖2,从面向对象的角度:在面向对象的角度上,我们这个时候其实就不会再关注把大象放进冰箱需要几步了,我们眼里看到的就只是冰箱,大象这两个对象,目的就是把大象放进去,至于过程是怎么放我们不关心,这个时候对于一件事情的完成就只是通过对象间的交互完成的,不注重具体的过程实施。
🌈二,类的定义和使用
如何定义一个类,如下:
// 创建类
class ClassName{
field; // 字段(属性) 或者 成员变量
method; // 行为 或者 成员方法
}
类名注意用大驼峰定义
示例:定义一个学生类
class Student{
// 1,字段,属性
public String name;
public int age;
// 2,方法
public void doClass(){
System.out.println("做作业!");
}
public void doTest(){
System.out.println("做试卷!");
}
}
🚩注意:
一般情况下,一个文件里面只定义一个类,main方法所在的类一般要使用public做修饰符,一个文件里面可以有多个类,public所修饰的类可以没有,但是有就只能有一个,并且此时类名必须与文件名相同
🌈三,类的实例化
🌟3.1,什么是类的实例化
我们定义类时,就相当于定义了一种新的自定义的类型,就和基本类型一样,我们可以通过它来定义实例,或者说对象。用类类型创建对象的这么一个过程,就叫做类的实例化
Student stu = new Student();//以上面的学生类而言,stu就是实例化对象的一个过程
🚩注意:
🌖1,我们在创建对象时,利用的是关键字new,一个类可以实例化多个对象。
🌖2,有了对象之后,我们可以用操作符 . 来访问和和使用我们的实例化的成员属性和方法。
假设有一个人的类别,我们实例化出一个对象,那它在内存中的简单布局如下:
🌈四,类有关细节总览
🌈五,static关键字
🌟5.1,修饰属性
static可以用在定义成员变量的时候,这个时候我们定义的变量叫做静态的成员变量。静态成员变量的特点就是:存储在方法区而并不是在对象的内部,只保存有一份。
那说到这,可能就有同学就要问了,你说一份就只有一份啊,谁告诉你的,证明看看!
class Test{
public int a;//实例化成员变量
public static int count;//静态成员变量
}
public class TestDemo220504 {
public static void main(String[] args) {
Test test1 = new Test();//new一个对象test1
test1.a++;
Test.count++;
System.out.println(test1.a);
System.out.println(Test.count);
System.out.println("=============");
Test test2 = new Test();//new一个对象test2
test2.a++;
Test.count++;
System.out.println(test2.a);
System.out.println(Test.count);
}
}
程序运行截图:
可以看到,我们实例化出了两个对象,test1,test2,对于实例化的成员变量而言,他们是分属于两个对象,处在不同的空间,所以在没有初始化的条件下默认值都是0,然后自增后自然就是1,所以看到的就是两个1,但是对于静态的成员变量而言,它是存储在方法区的,并且只有一份,也就是说你通过类名.变量名最终拿到的都是同一份count,所以我们看到输出一次是1,一次是2,明显区别于实例化的成员变量。
🌟5.2,修饰方法
static可以用在定义方法的时候,这样定义的方法就是静态的成员方法,如下:
class Test{
public int a;//实例化成员变量
public static int count;//静态成员变量
public static void func(){
//a = 10;这是不行的
count = 2;
System.out.println(count);
}
}
public class TestDemo220504 {
public static void main(String[] args) {
Test.func();
}
}
//程序最后输出2
🚩上面的func就是静态的成员方法,这里以下的点需要我们注意下:
🌖1,静态的方法是属于类,而不是属于对象。
🌖2,在调用静态的成员方法的时候,无需创建对象,可以直接用 类名.方法名。
🌖3,静态的成员方法可以访问静态的成员变量并且进行修改,但是,是不能够直接访问到非静态的成员变量的,需要你去使用对象或者类名去操作才可以,对于非静态的成员方法也是一样。(当然这些限制只是针对于静态的变量和方法,对于非静态的变量和方法是没有限制的,在非静态的方法里面使用静态的变量和方法都是可行的)
总结:虽然有了static关键字,但是一个方法是不是要定义为静态方法是视情况而定的,我们的main方法是static方法,所以之前在定义方法的时候就说不管那么多全定义为static的方法,因为mian里面这样才能够直接调用这些方法。
示例:
class Test{
public int a;//实例化成员变量
public static int count;//静态成员变量
public static void func(){
//a = 10;这是不行的
count = 2;
System.out.println(count);
}
}
public class TestDemo220504 {
public int a = 10;
public static void func1(){
}
public static void main(String[] args) {
func1();//同一个类里面的静态方法,main函数里面可以直接调用
TestDemo220504 test1 = new TestDemo220504();
test1.a = 100;
System.out.println(test1.a);
Test.func();
}
}
可以看到在public类TestDemo220504里面,main函数可以直接使用静态的成员方法,但是对于非静态的成员变量,只能通过对象去操作,不然就会直接报错,这是都在同一个类中。对于在一个类里面去使用另外一个类的成员变量和方法,不管是不是静态,你都只能通过对象和类名才能够操作到。
🌈六,封装
🌟6.1,封装的概念
封装简单来概括的话就是套壳屏蔽细节。比如我们使用的电脑就是将所有的硬件设施封装了起来,对外只提供键盘,鼠标,电源等外部连接设施来实现与计算机的交互。用专业的话术讲就是将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。
🌟6.2,访问限定符
访问权限用来控制方法或者字段能否直接在类外使用。一般情况下成员变量都设置为private私有的,方法接口都设置为public公有的。
Java里面提供了四种访问限定符。如下图:
🚩可能表中的描述比较术语,看的不是很明白,下面简单的介绍下以上的访问修饰符:
🌖public:就是公有的,所有人都可以看到,并且使用。
🌖private:就像是你的隐私,只有你自己知道。
🌖default:什么都不写的默认权限,限定范围是在同一个包里面,类似于同一个家族,只有家族内可以使用。
🌖protected:保护权限,这个在继承里面会详细介绍。
🌟6.3,封装的使用
说到封装,那我们可能会想,为什么要用封装,意义在哪?
这里有一个学生类,然后最开始它的名字属性我们定义的是name,但是在公司里面,不可能所有的类都是一个人写的,所以我们在很多情况下回去调用别人的类,但是如果我们不进行封装的话,有一天假如那个类的编写者突然想给这个变量换个名字,然后他一改,我们这里的代码就直接报红了,因为通过对象根本就找不到这个属性,然后我们又不知道到底改成了什么名字,所以回了避免这种情况,我们就直接把类都封装起来,让调用者不必考虑变量的名字,你也根本就无权访问的到,你根据我提供的公共接口使用就好,这样的话,就变得十分的nice了!
代码改进:
class Student{
private String myName;//封装是使用private修饰属性或者方法
private int age;
public void setMyName(String name){
myName = name;
}//提供一个外部赋值设置的接口
public String getMyName(){
return myName;
}//提供一个输出名字的外部接口
}
public class TestDemo220505 {
public static void main(String[] args) {
Student stu = new Student();
stu.setMyName("xiaowang");
String str = stu.getMyName();
System.out.println(str);
}
}
这样一来,我们就可以不用关心到底类的编写者是给属性定义的什么名字,我们按照他给我们的接口来使用就好了。
🚩注意:
public void setMyName(String myName){
myName = myName;
}
假如我们形参的名字与属性的名字相同也是很容易出现问题的,因为在局部上,同名变量会有局部优先的原则,所以这里其实就是我们的形参自己给自己赋值,而并没有给我们的属性赋值,那既然这样,我们一是最好不要用同名的形参,二是从根本上解决问题,同时也是符合阿里巴巴的编程规范的方法就是在我们的属性变量前面加上关键字this,这个代表的是这个类的对象的引用,所以即使同名也代表我们这个就是属性变量而不是形参本身。
public void setMyName(String myName){
this.myName = myName;
}
说到这,那可能又有同学又要问了,那我有多个属性怎么办,我又还一个个去写外部接口嘛,好麻烦…,emmm,听起来好像是酱紫哈,但是我想说的是,格局小了同学,你能考虑到这个问题,编译器的编写者能想不到,早就给你把方法提供好了~,你只需要动动你的小手手就好了!
当然,你以为这就完了嘛,当然不是,如果你想要对对象的所有的属性进行一个统一的输出,也无需我们自己去写show方法,编译器也会提供以字符串展示的方法。
上面所涉及到的代码总览:
class Student{
private String myName;
private int age;
public String getMyName() {
return myName;
}
public void setMyName(String myName) {
this.myName = myName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override //注解:指的是这个方法是重新写的
// 重写了一下Object类的toString方法,
// 让它能够以字符串的形式打印我们对象的属性的值,不用再自己定义show方法
public String toString() {
return "Student{" +
"myName='" + myName + '\'' +
", age=" + age +
'}';
}
// public void setMyName(String myName){
// this.myName = myName;
// }//提供一个外部赋值设置的接口
// public String getMyName(){
// return myName;
// }
}
public class TestDemo220505 {
public static void main(String[] args) {
Student stu = new Student();
stu.setMyName("xiaowang");
String str = stu.getMyName();
//System.out.println(str);
System.out.println(stu);//直接打印对象的值,如果上面没有重写Object的toSting方法,那么打印的就是 类名 + @ + 地址的哈希值
//为什么不用对象名.toString呢,可以用,但是没有上面的方法方便,其实println底层也会调用toString,所以没必要用对象名去调用
}
}
今天的分享就是这么多了,因为后面还有内容没有看完,所以就先更新这么多,大家记得持续关注喔,当然,如果觉得写的不错的话还请点点赞咯,十分感谢呢!🥰🥰🥰