JavaSE:类和对象
Posted Two_Fly
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE:类和对象相关的知识,希望对你有一定的参考价值。
类和对象
类和对象的认识
面向对象和面向过程
**面向过程:**面向过程就是分析出实现某些需求所需要的步骤,然后同股票函数逐步实现,依次调用
**面向对象:**面向对象是把整个需求按照功能、特点划分,将这些存在共性的部分封装成对象,当解决一个问题的时候,面向对象会把事物抽象成对象的概念,然后给对象赋一些属性和方法,然后让每个对象去执行自己的方法,问题得到解决。
类和对象的概念
类就是一类对象的统称,对象就是这一类具体化的一个实例。打个通俗的比喻就是:制作月饼的模具就相当于我们的类,而利用模具做出来的月饼就是我们通过月饼模具“实例化”的一个对象。总的来说:类相当于一个模板,对象是由模板产生的样本,一个类,可以产生无数的对象。声明一个类就是创建一个新的数据类型,而类在 Java 中属于引用类型, 所以Java 使用关键字 class 来声明类。
类的定义与实例化
//类的定义
class 类名 {
成员变量;
成员方法;
}
//类的实例化-->对象
类名 对象名 = new 类名();
class为定义类的关键字,{}中为类的主体,类中的元素称为:成员属性,类中的函数称为:成员方法。
class Person {
public String name;
public int age;
public String sex;
public void eat() {
System.out.println(name+"要吃饭");
}
public void sleep() {
System.out.println(name+"要睡觉");
}
}
稍后我们会解释一直未解释的public
以及我们这里写方法时为什么没加static
用类创建对象的过程,称为类的实例,一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量,new关键字用于创建一个对象,使用 . 来访问对象中的属性和方法
class Person {
public String name = "lrf";
public int age = 19;
public String sex = "man";
public void eat() {
System.out.println(name+"要吃饭");
}
public void sleep() {
System.out.println(name+"要睡觉");
}
}
class Main {
public static void main(String[] args) {
Person person = new Person();//类的实例化-->创建对象
person.eat();
person.sleep();
}
}
类和对象的内存结构
person
是一个变量,只是这个变量里储存的是地址,所以这个变量也被叫做引用
类的成员
字段/属性/成员变量
在类内,在方法外部定义的变量我们称为 “字段” 或 “属性” 或 "成员变量,用于描述一个类中包含哪些数据
class Person {
public String name = "lrf";//字段/属性/成员变量
public int age = 19;//字段/属性/成员变量
public String sex ;//字段/属性/成员变量
public void eat() {
System.out.println(name+"要吃饭");
}
public void sleep() {
System.out.println(name+"要睡觉");
}
}
class Main {
public static void main(String[] args) {
Person person = new Person();//类的实例化-->创建对象
//字段的访问
System.out.println(person.name+"的年龄是:"+person.age);
//字段的默认值
System.out.println(person.name+"的性别是:"+person.sex);
}
}
总结:
1.使用.
来访问对象的字段,访问包含读和写
2.一个对象的字段如果没有显式设置初始值,那么会被设置一个默认的初值
默认值规则
- 8种基本数据类型, 默认值为 0.
boolean
类型,默认值为false
- 引用类型(
String
,Array
, 以及自定制类), 默认值为null
方法
我们之前以及讲过了方法,他可以理解为函数的别名,我们定义的方法用来描述对象的行为
class Person {
public String name;
public int age;
public void describe() {
System.out.println("我叫"+name+",是一名"+age+"岁的成年男性,"+"也被人称为“法外狂徒”"+name);
}
}
class Main {
public static void main(String[] args) {
Person person1 = new Person();//类的实例化-->创建对象
person1.age = 23;
person1.name = "张三";
person1.describe();
Person person2 = new Person();
person2.age = 13;
person2.name = "李四";
person2.describe();
}
}
此处的describe
方法, 表示我们实例化对象之后,这个对象具有一个"自我介绍"的行为,我们类中定义的方法是和实例化的对象相关联的,如果创建了其他实例, 那么describe
的行为就会发生变化
static关键字
class staticTest {
public static int count=0;
public int age=0;
}
class Main {
public static void main(String[] args) {
staticTest person1 = new staticTest();
person1.count++;
person1.age++;
System.out.println("person1.count="+person1.count);
System.out.println("person1.age="+person1.age);
staticTest person2 = new staticTest();
person2.count++;
person2.age++;
System.out.println("person2.count="+person1.count);
System.out.println("person2.age="+person1.age);
}
}
在我们为了解static的作用之前,我们认为应该输出person1.count=1
和person1.age=1
,person2.count=1
和person2.age=1
,毕竟在定义类时,两者都初始化为0,那么我们运行以下上述代码,结果真如我们所想吗?
age
变量如我们所想象的一样,那么count
变量为什么会是1和2呢?
由static修饰的变量和方法被称作静态变量、静态方法,又称为类变量。类方法。静态成员是属于类所有的,区别于个别对象,可以在本类或其他类中使用类名和.
运算符调用。这里先接受以下Java内存中的方法区,然后我们从内存角度去剖析以下具体的原因
**方法区:**保存在着被加载过的每一个类的信息,这些信息由类加载器在加载类的时候,从类的源文件中抽取出来,static变量和方法的信息也保存在方法区中
以下是内存角度分析:
注意&总结:
1.普通的方法内部,不能够定义静态的变量
2.静态方法的内部不可以调用普通方法
3.我们曾经说写方法都要统一加上了static,是因为我们之前写的方法只有被static修饰后才能直接调用而不依赖于对象
4.一个对象存储到哪里,和是否被final修饰没有任何关系
封装
访问限定修饰符
private
/ public
这两个关键字称为访问限定修饰符
- public修饰的成员变量或者成员方法,可以直接被类的调用者使用
- private修饰的成员变量或者成员方法,不能被类的调用者使用
class Test {
public int count=1;
public int age=13;
}
class Main {
public static void main(String[] args) {
Test test = new Test();
System.out.println(test.age);
System.out.println(test.count);
}
}
当我们将变量使用public修饰时,在类外访时需要了解Test类内部的实现,才能够使用这个类,学习成本较高,一旦类的实现者修改了代码(把count
改成num
),那么类的使用者就需要大规模的修改代码,这使得代码的可维护性较低,维护难度较大,维护成本较高。为了解决这些问题,提高我们代码的可维护性,我们提出了封装这个概念。
封装可以被认为是一个保护罩,防止该类的代码和数据被外部类定义的代码随机访问。要访问该类的代码和数据,必须通过严格的接口控制,我们的getter和setter方法来源就是如此。
getter和setter方法
我们使用private封装属性, 并提供public的getter和setter方法供类的调用者去访问这些属性。
class Test {
private String name = "张三";
private int age = 23;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Main {
public static void main(String[] args) {
Test test = new Test();
System.out.println(test.getName()+"的年龄是:"+test.getAge());
test.setName("李四");
test.setAge(33);
System.out.println(test.getName()+"的年龄是:"+test.getAge());
}
}
this表示当前对象引用(注意不是当前对象). 可以借助 this 来访问对象的字段和方法,稍后我们详细介绍
注意&总结:
1.getName
即为getter
方法,表示获取这个成员的值,setName
即为setter
方法,表示修改这个成员的值.
2.当set
方法的形参名字和类中的成员属性的名字一样的时候,如果不使用this
,就相当于自己给自己赋值,this
表示当前对象的引用
3.不是所有的字段都一定要提供 setter / getter
方法,要根据实际情况决定提供哪种方法
IDEA生成getter / setter
方法快捷方法:
构造方法
一个对象的产生要有两个过程:
1.为对象分配内存
2.调用合适的构造方法
什么是构造方法?
构造方法是一种特殊方法, 使用关键字new实例化新对象时会被自动调用, 用于完成初始化操作,就算我们在类中没有实现构造方法,那么编译器也会自动帮我们生成一个无参的构造方法,也就是说:一个类至少有一个构造方法
基本语法
1.方法名与类名相同
2.构造方法没有返回值类型的声明
示例:
class Test {
public String name ;
public int age;
public Test(int age) {
this.age = age;
}
public Test(String name) {
this.name = name;
}
public Test(String name, int age) {
this.name = name;
this.age = age;
}
}
class Main {
public static void main(String[] args) {
Test test1 = new Test(1);//参数为age的构造方法
System.out.println("test1: ");
System.out.print(test1.age+" ");
System.out.println(test1.name);
Test test2 = new Test("wuhu~");//参数为name的构造方法
System.out.println("test2: ");
System.out.print(test2.age+" ");
System.out.println(test2.name);
Test test3 = new Test("wuhu~",1);//两个参数的构造方法
System.out.println("test3 ");
System.out.print(test3.age+" ");
System.out.println(test3.name);
}
this关键字
this表示当前对象引用,注意不是当前对象. 在一些特殊情况下必须借助 this来访问对象的字段和方法
class Test {
public String name ;
public int age;
public Test(String name, int age) {
this.name = name;
this.age = age;
}
}
class Main {
public static void main(String[] args) {
Test test3 = new Test("wuhu~",1);//两个参数的构造方法
System.out.println("test3 ");
System.out.print(test3.age+" ");
System.out.println(test3.name);
}
}
例如我们在写构造方法时,我们传入的参数名和成员变量名如果是相同的,那么就会造成歧义导致程序结果与预期不符,当我们使用this关键字时,便可以对两个相同名字的变量进行区分。
class Test {
public String name ;
public int age;
public Test(String name, int age) {
name = name;
age = age;
}
}
class Main {
public static void main(String[] args) {
Test test3 = new Test("wuhu~",1);//两个参数的构造方法
System.out.println("test3 ");
System.out.print(test3.age+" ");
System.out.println(test3.name);
}
}
代码块
代码是指使用{}定义的一段代码
普通代码块
一般很少这样使用
class Test {
public String name ;
public int age;
public Test(String name, int age) {
this.name = name;
this.age = age;
}
}
class Main {
public static void main(String[] args) {
//定义一个普通代码块
{
System.out.println("我是普通代码块");
String str = "hhh";
System.out.println(str);
}
}
}
构造代码块与静态代码块
实例代码块也称为构造代码块
- 构造代码块的作用是给对象进行初始化。
- 对象一建立就运行构造代码块了,而且优先于构造函数执行。这里要强调一下,有对象建立,才会运行构造代码块,类是不能调用构造代码块的,而且构造代码块与构造函数的执行顺序是前者先于后者执行。
- 构造代码块与构造函数的区别是:构造代码块是给所有对象进行统一初始化,而构造函数是给对应的对象初始化,因为构造函数是可以多个的,运行哪个构造函数就会建立什么样的对象,但无论建立哪个对象,都会先执行相同的构造代码块。也就是说,构造代码块中定义的是不同对象共性的初始化内容。
静态代码块
- 它是随着类的加载而执行,只执行一次,并优先于主函数。具体说,静态代码块是由类调用的。类调用时,先执行静态代码块,然后才执行主函数的。
- 静态代码块其实就是给类初始化的,而构造代码块是给对象初始化的。
- 静态代码块中的变量是局部变量,与普通函数中的局部变量性质没有区别。
- 一个类中可以有多个静态代码块
可根据以下代码以及运行结果去对照分析上述规则:
class Test {
public static int num = 233;
public String name ;
public int age;
public Test(String name, int age) {
this.name = name;
this.age = age;
}
{
System.out.println("现在执行到了实例代码块");
num = 23;
name = "hhh";
System.out.println("在执行到实例代码快时:");
System.out.println("name = "+name+" age = "+age);
}
static{
num = 123;
System.out.println("现在执行到了静态代码块");
}
}
class Main {
public static void main(String[] args) {
System.out.println(Test.num);//调用类(未实例化对象)
Test test = new Test("hehe",1);
System.out.println(以上是关于JavaSE:类和对象的主要内容,如果未能解决你的问题,请参考以下文章