面向过程编程:你关注的是过程
面向对象编程:你关注的是对象
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
JAVA是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
class Preson{
public String name;// name:实例成员变量
public int age;
public static int a=10;//静态成员变量 方法区
//name a 叫做字段/属性/成员变量
//访问修饰限定符:权限 public private protected 默认访问权限
}
// 行为,方法
public void eat(){// eat sleep :实例成员方法
System.out.println("吃饭");
}
public void sleep(){
System.out.println("睡觉");
}
public static void func(){ //静态成员方法
System.out.println("静态成员方法");
}
public static void main(String[] args){
//实例化对象 真正意义上有了一个实体
//person是一个引用
Person person=new Person();
person.name="";
System.out.println(person.name); //如果没有初始化,打印就是一个默认的零值,如果是引用类型,那麽就是null,如果是简单类型,那麽就是这种类型所对应的默认值 Boolean默认值false char的默认值‘\u0000’
Peason.func();//对于静态成员变量和静态成员方法,访问方式:Peason.func()
}
对于静态的属性或者方法,是不依赖于对象的。
如何定义一个类
// 创建类
class 类名{
field(字段);//成员属性,定义在类的内部,方法外部的变量
method;//成员方法
}
// 实例化对象
<class_name> <对象名> = new <class_name>();
当用sout打印一个引用的时候,那麽就会默认调用Object的toString()方法
静态成员变量或者成员方法是否可以通过对象的引用来进行访问?
可以,合法不合理,建议规范类名去访问。
一个类可以产生/实例化多个对象
Peason peason1=new Peason();
Peason peason2=new Peason();
Peason peason3=new Peason();
Peason peason4=new Peason();
初始化成员变量方式
1.就地初始化
public String name=“张三”;
2.默认初始化
public String name;
public int age;
3.类外进行初始化
public void eat(){// eat sleep :实例成员方法
System.out.println(name+"吃饭");
}
public static void main(String[] args){
Peason peason=new Peason();
peason.name="zhangsan";
peason.age=19;
peason.eat();
}
静态总结
1.静态成员变量或者成员方法,是不依赖于对象的
2.静态的成员变量只有一份,存在了方法区中
3.静态的方法内部是不可以访问非静态的数据的
@Override:重写
class Person {
public int age;//实例变量 存放在堆的对象内
public String name;//实例变量
public String sex;//实例变量
public static int count;//类变量也叫静态变量,编译时已经产生,属于类本身,且只有一份。存放在方法区
public final int SIZE = 10;//被final修饰的叫常量,也属于对象。 被final修饰,后续不可更改。(变量存在于哪个区域和是否被final修饰没有关系)堆
public static final int COUNT = 99;//静态的常量,属于类本身,只有一份 被final修饰,后续不可更改
//真实的项目过程中,使用static final
}
封装
OPP语言:Java, C++
面向对象的特征:封装,继承,多态
封装的意义:让类的调用者能够对类的学习成本降低
private实现封装
所有被private所修饰的成员变量或成员方法都只能在类内进行访问,类外要进行访问,需要提供公有的接口
private/ public 这两个关键字表示 “访问权限控制” .
被 public 修饰的成员变量或者成员方法, 可以直接被类的调用者使用. 被 private 修饰的成员变量或者成员方法, 不能被类的调用者使用.
换句话说, 类的使用者根本不需要知道, 也不需要关注一个类都有哪些 private 的成员. 从而让类调用者以更低的成本来使用类.
直接使用Public
class Person {
public String name = "张三";
public int age = 18; }
class Test {
public static void main(String[] args) {
Person person = new Person();
System.out.println("我叫" + person.name + ", 今年" + person.age + "岁");
}
}
// 执行结果
我叫张三, 今年18岁
这样的代码导致类的使用者(main方法的代码)必须要了解 Person 类内部的实现, 才能够使用这个类. 学习成本较高
一旦类的实现者修改了代码(例如把 name 改成 myName), 那么类的使用者就需要大规模的修改自己的代码, 维护成本较高
使用 private 封装属性, 并提供 public 方法供类的调用者使用.
class Person {
private String name = "张三";
private int age = 18;
public void show() {
System.out.println("我叫" + name + ", 今年" + age + "岁");
}
}
class Test {
public static void main(String[] args) {
Person person = new Person();
person.show();
}
}
// 执行结果
我叫张三, 今年18岁
此时字段已经使用 private 来修饰. 类的调用者(main方法中)不能直接使用. 而需要借助 show 方法. 此时类的使用者就不必了解 Person 类的实现细节.
同时如果类的实现者修改了字段的名字, 类的调用者不需要做出任何修改(类的调用者根本访问不到 name, age这样的字段).
getter和setter方法
class Person {
private String name;//实例成员变量
private int age;
public void setName(String name){ //setName 即为 setter 方法, 表示设置这个成员的值
//name = name;//不能这样写
this.name = name;//this代表当前对象的引用,表示调用该方法的对象
}
public String getName(){ //getName 即为 getter 方法, 表示获取这个成员的值.
return name;
}
public void show(){
System.out.println("name: "+name+" age: "+age);
}
}
public static void main(String[] args) {
Person person = new Person();
person.setName("caocao");
String name = person.getName();
System.out.println(name);
person.show();
}
// 运行结果
caocao
name: caocao age: 0
1.当set方法的形参名字和类中的成员属性的名字一样的时候,如果不使用this, 相当于自赋值. this 表示当前实例的引用.
2.不是所有的字段都一定要提供 setter / getter 方法, 而是要根据实际情况决定提供哪种方法.
3.在 IDEA 中可以使用 alt + insert (或者 alt + F12) 快速生成 setter / getter 方法. 在 VSCode 中可以使用鼠标右键菜单 -> 源代码操作 中自动生成 setter / getter 方法.
方法是私有的,只能在类内进行访问,类外要进行访问,要有公有的接口
private void func(){
System.out.println("func()");
}
public void func2(){
func();
}
构造方法
本质还是一个方法,但是没有返回值
实例化/创建一个对象分几步?
两步,为对象分配内存,调用合适的构造方法,说明构造方法不止一个,可能有多个
如果一个类没有写任何的构造方法,那麽编译器会为当前类生成一个默认的构造方法,而这个构造方法是不带有参数的构造方法。
只要自己写了其他的构造方法,那么编译器就不会自动生成一个不带参数的构造方法
重载:
1.方法名相同
2.参数列表不同
3.返回值不做要求
class Person {
private String name;//实例成员变量
private int age;
private String sex;
//默认构造函数 构造对象
public Person() {
this.name = "caocao";
this.age = 10;
this.sex = "男";
}
//带有3个参数的构造函数
public Person(String name,int age,String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main{
public static void main(String[] args) {
Person p1 = new Person();//调用不带参数的构造函数 如果程序没有提供会调用不带参数的构造函数
p1.show();
Person p2 = new Person("zhangfei",80,"男");//调用带有3个参数的构造函数
p2.show();
}
}
// 执行结果
name: caocao age: 10 sex: 男
name: zhangfei age: 80 sex: 男
this关键字
this.属性:访问当前对象的属性
this.func( ):调用当前对象的方法
this( ):调用当前对象的构造方法
方法如果是静态的,就不能用this
this( ):必须放在第一行,且只能存在构造方法内部
new Student():匿名对象
认识代码块
什么是代码块?
根据代码块定义的位置以及关键字,又可分为以下四种:
普通代码块
构造代码块
静态代码块
同步代码块
普通代码块:
public class Main{
public static void main(String[] args) {
{
//直接使用{}定义,普通方法块
//本地代码块:定义在方法内部的代码块
}
}
静态代码块:
class Person{
private String name;//实例成员变量
private int age;
private String sex;
private static int count = 0;//静态成员变量 由类共享数据 方法区
public Person(){
System.out.println("I am Person init()!");
}
//实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
//静态代码块
static {
count = 10;//只能访问静态数据成员
System.out.println("I am static init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
静态代码块不管生成多少个对象,其只会执行一次,且是最先执行的。
静态代码块执行完毕后, 实例代码块(构造块)执行,再然后是构造函数执行。
如果都是静态的,和顺序有关系