声明:该专栏本人重新过一遍java知识点时候的笔记汇总,主要是每天的知识点+题解,算是让自己巩固复习,也希望能给初学的朋友们一点帮助,大佬们不喜勿喷(抱拳了老铁!)
Java学习day06:面向对象基础,构造方法,成员/局部变量
一、从生活角度理解面向过程和面向对象
1.面向过程:
程序自上而下执行,不牵涉到类和对象的操作。本质是代码自己完成自己的功能,冒泡排序是面向过程的,也就是说,亲力亲为 都是面向过程的。
2.面向对象:
程序是靠对象完成一定的功能,Arrays.sort(arr) 这个就是面向对象的,借助于对象来实现功能的
大家可以这么想,面向过程就是啥子事情都自己干,而面向对象则是专业的事情找专业的人干,比如做饭,有的人选择自己买菜自己做饭,有的人直接交给保姆完成,从生活上来说,我认为面向过程更重要,而从工作上来说,我认为面向对象更重要
二、类和对象概念
1.类:
对一切相似事物的统称,是一个泛泛的概念。可以用来描述事物的特征和行为
特征:就是一类事物的属性,比如人的年龄 身高 体重 性别
在Java代码中使用变量来表示一个类的特征或者属性
int age;
double height;
是静的东西
行为:就是动作 吃饭 睡觉 敲代码
在Java中使用方法来描述一个类的行为
是动的东西
只要把握好特征和行为就可以写好一个类了
2.对象:
是一个具体的实体。是这是真实存在的。在类的基础之上孵化出来的。
举一个例子:狗是一个类,而我家养的哈士奇小峰就是一个对象。
三、声明类的方法
语法格式:
[public] class 类名 {
对于当前类的属性的描述
对于当前类的行为的描述
}
这里的public可以省略的 ,而且很多时候还不能用public,当写在一个文件夹里的时候,毕竟文件名要跟public后面跟的类名一致,就只能用一个public,所以建议就是直接记住声明类没有public。给一个示例:
class Person {
//人类:
//属性: 姓名 年龄 性别 身高
//行为: 吃饭 睡觉
//类下面的属性: Java使用变量来描述
//在类中 变量最好不要赋值
String name; //名字 null
int age;//年龄 0
char sex;//性别
double height;//身高0.0
//在类中后书写行为 Java使用方法来描述行为
//public static void eat() {}
//今天学的内容,和之前方法的声明不一样,去掉static即可
public void eat () {
System.out.println("中午吃酸菜鱼");
}
public void sleep () {
System.out.println("中午不睡,下午崩溃");
}
四、对象的创建
一个类声明好以后,即使不使用它,它也是一直存在,咱们可以借助于对象衍生出一个实体,
类可以衍生出来一个对象。类相当于一个模子,可以造出来一个实体。
造出对象的目的是为了执行属性的复制和方法的调用的
综上:先有类,再有对象
对象的创建在main主函数中。目的是为了执行这个对象代码
Java类的语法格式:
类名 对象的名字 = new 类名();
示例:
//Demo1叫测试类 里面有main主函数
public class Demo1 {
public static void main(String[] args) {
//类名 对象的名字 = new 类名();
//这个对象是由类衍生出来的,就意味着类下面的属性可以使用
//类下面的方法我可以调用
Person person = new Person();
//对属性进行赋值
//person的名字 为 狗蛋
person.name = "狗蛋";
person.age = 78;
person.sex = '男';
person.height = 98.7;
//以上是对对象的属性进行赋值
//将对象的属性值取出来
System.out.println(person.name + person.age + person.sex + person.height);
//方法的调用 对象.方法名字();
person.eat();
person.sleep();
}
}
五、实体类和测试类在同一个Java文件中
1.注意事项:
需要注意的两点:实体类和测试类写在同一个文件中的时候,实体类不能带public修饰符
第二点是实体类可以写在测试类前面,也可以写在测试类后面,是不影响的,但是区分好,不能写在测试类里面了
示例:
class Pig {
String name;
double weight;//体重
char sex;//性别
public void eat () {
System.out.println("猪吃白菜!!!");
}
public void sleep () {
System.out.println("猪睡觉打呼噜");
}
}
public class Main {
public static void main(String[] args) {
Pig pig = new Pig();
pig.name = "大黄";
pig.weight = 100.1;
pig.sex = '公';
System.out.println(pig.name + pig.weight + pig.sex);
pig.eat();
pig.sleep();
}
public class Main {
public static void main(String[] args) {
Pig pig = new Pig();
pig.name = "大黄";
pig.weight = 100.1;
pig.sex = '公';
System.out.println(pig.name + pig.weight + pig.sex);
pig.eat();
pig.sleep();
}
}
class Pig {
String name;
double weight;//体重
char sex;//性别
public void eat () {
System.out.println("猪吃白菜!!!");
}
public void sleep () {
System.out.println("猪睡觉打呼噜");
}
}
这两种写法都没有任何问题,但如果要把pig类写在main方法里面,那就需要注意了,由于Pig类是非静态的内部类,它与外部类的实例相关联。在静态方法main中,你无法直接引用非静态内部类的实例变量。此时可以将Pig类声明为静态内部类,或者将它提取到单独的文件中,而实际开发中都会是把实体类重新写道一个文件中的
总结:当你将Pig类提取到Main类的外部时,它变成了一个独立的类,可以直接访问和修改其成员变量,不需要通过对象实例来引用非静态变量。而当你将Pig类声明为Main类的内部类时,它与外部类的实例相关联,需要通过对象实例来引用非静态变量。
可能这里很多朋友还不清楚静态和非静态,这个后面会讲的,先拓展了解就是。
2.内部类和外部类的区别:
区别 | 内部类 | 外部类 | 详细解释 |
访问权限 | 内部类可以访问外部类的私有成员 | 外部类不能直接访问内部类的私有成员 | 这是因为内部类被认为是外部类的一部分,所以可以访问外部类的所有成员,包括私有成员。然而,外部类无法直接访问内部类的私有成员,因为内部类的私有成员对于外部类来说是不可见的。 |
关联性 | 内部类可以访问和修改外部类的成员变量和方法,包括私有成员。 | 外部类无法直接访问内部类的成员变量和方法,需要通过内部类的实例来访问。 | 内部类与外部类之间存在一种关联关系。 |
创建方式 | 要创建内部类的实例,首先需要创建外部类的实例,然后使用外部类的实例来创建内部类的实例。 | 外部类的实例可以直接创建,不需要依赖其他类的实例。 | 内部类的实例必须依赖于外部类的实例。 |
静态性 | 内部类可以是静态的或非静态的 | 外部类只能是非静态的。 | 静态内部类与外部类没有关联,可以直接创建静态内部类的实例。非静态内部类与外部类相关联,需要通过外部类的实例来创建非静态内部类的实例。 |
六、构造方法
1.无参构造:
构造方法的目的是为了初始化对象的,换句话说,可以对对象的属性进行赋值。对象创建其实是依据构造方法创建的,因此可以在构造方法里对对象进行赋值等操作。
在不写构造方法的情况下,会默认生成一个无参构造的。
同时注意:构造方法必须写在实体类中
语法格式:
public 类名() {
}
示例:
class Person{
String name;
int age;
//无参构造
public Person(){
System.out.println("无参构造");
//this指的是当前对象,你创建哪个对象,this指的就是那个
//打印当前对象的内存地址,和main方法里打印的是一样的
System.out.println(this);
this.name="okk";
this.age=20;
}
}
public class Main {
public static void main(String[] args) {
//当new Person()的时候就会去自动调用无参构造方法去执行无参构造方法中的方法体
Person person=new Person();
//打印的就是person对象的内存地址
System.out.println(person);
person.name="kkk";
//此时打印的age是初始化的20.但是名字却成了kkk。因为后面赋的值就会覆盖掉初始化的值
System.out.println(person.age);
System.out.println(person.name);
}
2.有参构造:
语法格式:
public 类名 (参数) {
初始化条件;
}
有参构造实际上就是提前给对象的属性赋值,不需要再在main函数依次赋值
参数可以声明一个/多个,但是要知道,参数只是形参,如果这样写就是错误的,因为两个是一样的,形参可以取任何名字,当然一般会取成跟属性名一样的。
这里注意一个初学者易犯的错误:两个是一样的
//和下面的有参构造一模一样!!!
// public Cat (String kind) {
// this.kind = kind;
// }
//声明一个有参构造方法
public Cat (String name) {
this.name = name;
}
同时还要注意一点,如果写了有参构造,默认的无参构造方法就没有了,如果想用,就需要再写一遍
示例:
class Cat {
String name;
String kind;
int age;
public Cat() {
}
//声明一个有参构造方法
public Cat (String name) {
this.name = name;
}
//带有三个参数 构造方法
public Cat (String name, String kind, int age) {
this.name = name;
this.age = age;
this.kind = kind;
}
}
public class Demo3 {
public static void main(String[] args) {
Cat cat = new Cat("狗蛋");
System.out.println(cat.name);
//new对象的时候依据构造方法来创建对象
Cat cat1 = new Cat("毛蛋", "波斯", 3);
System.out.println(cat1.name);
System.out.println(cat1.age);
System.out.println(cat1.kind);
//一旦写了有参构造方法以后,默认的无参构造方法就没有了
Cat cat2 = new Cat();
cat2.name = "Tom";
cat2.age = 4;
cat2.kind = "蓝猫";
}
}
3.对象在内存中如何存储:
先复习:栈内存,存的是八大基本数据类型的数据:byte short int long float double char boolean
存的是对象的引用,等号左边的
而堆内存,存的是对象的全部数据
七、构造代码块(了解)
注:开发中已经不用了,但是后面会讲静态代码块。所以这里提一下
构造代码块的目的也是对对象进行初始化的。功能和构造方法一样的
语法格式:
{
语句体
}
注意事项:
1.构造代码块必须写在实体类中
2.先执行的是构造代码块,再执行构造方法,不管构造代码块的位置在前还是后,这是由Java虚拟机决定的,记住就行。
示例:
class Tiger {
String name;
int age;
//再声明一个构造方法
public Tiger () {
this.name = "haha";
System.out.println("我是无参构造方法");
}
//先写一个构造代码块
{
this.name = "嘻嘻";
System.out.println("我是构造代码块");
}
}
public class Demo5 {
public static void main(String[] args) {
//先执行实体类中构造代码块 然后再执行构造方法
Tiger tiger = new Tiger();
System.out.println(tiger.name);
}
}
这里最终打印的name是haha,就是因为构造代码块先执行,所以后执行的构造方法把嘻嘻值给覆盖了。
八、成员变量和局部变量
1.局部变量:
抓住一点:大括号里面的那个变量只能在大括号里面来使用的
示例:
for (int i = 0; i < 5; i++) {
//上面的i就是for循环的局部变量,出了for循环还能用吗?不能
//紧紧围绕着一个东西就是那个大括号
System.out.println(i);
}
//System.out.println(i);
//此时就会报错,因为i的作用域只在for循环里
此时的i对于for循环来说是成员变量(当然这种说法是有问题的),对整个类来说就是局部变量。
2.成员变量:
定义在实体类中的大括号的后面,又叫属性
示例:
class Person {
//name 和 age都是成员变量
String name;
int age;
//作用域 是作用再整个类中 的,只要在类中都可以使用当前的成员变量
public void eat () {
double weigt;//局部的变量
System.out.println(name + age);
}
}
3.区别:
今天没有习题,理解为主,特别是理解类和对象概念,以及如何创建类和对象,类的构造方法,成员变量和局部变量等,是现在必须要理解的,大家可以自己试着写几个类,把今天讲的知识点都用上。