-
面向对象和面向过程区别:
- 从语言出发:
- C:完全面向过程
- C++:一半面向过程,一半面向对象
- Java:完全面向对象
- 开发方式:
- 面向过程
- 注重实现功能步骤,注重实现功能的因果关系。
- 第一步干什么,第二步干什么。
- 缺点:耦合度高,扩展能力差。
- 优点:对于小型项目,效率高
- 采用面向过程开发一台计算机:一体机
- 采用面向对象开发一台计算机:组合机
- 面向对象
- 将现实世界分隔成不同的单元,然后每一个单元实现成对象,然后给一个环境驱动一下,让各个对象之间写作起来形成。(更符合人类思维方式)
- 优点:耦合度低,扩展性高
- 面向过程
- 面向过程主要关注的是:实现步骤以及整个过程
- 面向对象主要关注的是:对象A,对象B,对象C。。。然后进行组合。
- OOA:面向对象分析
- OOD:面向对象设计
- OOP:面向对象编程
- 实现软件过程:分析(A)->设计(D)->编程(P)。
- leader 领导、组长
- team 团队
- PM 项目经理 Project Manager
- 面向对象三大特征:封装、继承、多态
- 从语言出发:
-
类和对象
主要一词:对象
类:是一个抽象的概念,一个模板,是思考、总结、抽象的一个结果。本质是现实世界中的某些食物的共同特征,提取出来的一个概念,一个模板。
对象(实例):实际存在的实体。
要想得到对象,必须先定义类,对象是通过类这个模板创造出来的。
类是一个模板:类中描述所以对象的共同特征信息。
对象是通过类创建出的个体。
通过类创建对象的过程叫实例化。
抽象:多个对象具有共同特征,进行思考总结抽取特征的过程。
类:包括:状态特征(属性)、动态特征(方法)
public class Student{ //属性: 姓名 性别 身高 //方法 sing dance study }
要求具备:观察+抽象能力,把现实世界中的对象手中的共同特征抽象成类,然后通过类实例化对象,让对象之间互相写作形成系统,模拟现实世界。
-
类的定义
[修饰符列表] class 类名{ //类体=属性+方法 //属性在代码中以变量形式存在(描述状态)。 //方法描述动作行为。 }
因为属性是数据,数据在程序中存在变量中。
变量:在方法体内声明:局部变量;类内方法体外声明变量:成员变量(属性)。
成员变量可以不手动赋值。
public class Student{ int id; String name; int age; boolean gender; String addr; }
public class StudentTest{ public static void main(String[] args){ //new 类名(); 创建对象。 //new是一个运算符,专门负责对象的创建。 //类型 变量名 = new 类名(); //s1叫引用 Student s1 = new Student(); //类型:基本数据类型+引用数据类型。 //Java中所有的类都属于引用数据类型。 } }
创建对象的个数没有限制,只要有模板类就行。
关于编译的过程:按说先编译Student.java ,再编译StudentTest.java。
但是对于编译器来说,编译StudentTest.java时,会自动找Student.class文件,如果没有,会自动编译Student.java文件,生成Student.class文件。
第一种方式:javac Student.java javac StudentTest.java
第二种方式:javac StudentTest.java
第三种方式:javac *.java
在语法上实现对象创建:类名 变量名 = new 类名();
-
成员变量没有手动赋值都默认赋值。
- 类型 默认值
- byte 0
- short 0
- int 0
- long 0L
- float 0.0F
- double 0.0
- boolean false
- char \u0000
- 引用数据类型 null
实例变量(属性):对象级别的变量。
实例变量访问时,必须先实例化。不能通过类名直接访问。
对象和引用的区别:对象是通过new出来的,在堆内存中存储。引用 是但凡是变量并且变量中保存了堆内存中对象的变量。
//访问实例变量: 引用.实例变量名
public class 学生{ int 学号; String 姓名; }
public clss 学生测试{ public static void main(String[] args){ 学生 张三 = new 学生(); System.out.println(张三.学号); System.out.println(张三.姓名); 张三.学号 = 111; 张三.姓名 = "这里"; System.out.println(张三.学号); System.out.println(张三.姓名); } }
public class User{
int id;
String user;
}
public class UserTest{
public static void main(String[] args){
User u1 = new User();
u1.id = 111;
u1.user = "张三";
System.out.println(u1.id);
System.out.println(u1.user);
}
}
-
借鉴:
image.png
public class Addr{
String city;
String jd;
}
public class User{
String username;
int id;
Addr addr;
}
public class Test{
public static void main(String[] args){
User u = new User();
System.out.println(u.id);
System.out.println(u.username);
System.out.println(u.addr);
Addr c = new Addr();
c.city = "beij";
c.jd = "daxing";
u.addr = c;
System.out.println(u.addr.city);
}
}
- 画内存图注意事项:
- 不要体现代码在内存图中,主要体现数据
- 图形,有先后顺序。
- 为什么画内存图
- 有了内存图,程序不允许,也知道结果
- 有了内存图,有助于调试程序
- 引用是存储对象内存地址的一个变量
- 对象是堆里new出来的。
- 引用一定是局部变量吗? 不一定。可以是成员变量
public class T{
A a;
public static void main(String[] args){
D d = new D();
C c = new C();
B b = new B();
A a = new A();
T t = new T();
//以下赋值不写会出现空指针异常。
c.d = d;
b.c = c;
a.b = b;
t.a = a;
//通过t访问d中的i
System.out.println(t.a.b.c.d.i);
}
}
class A{
B b;
}
class B{
C c;
}
class C{
D d;
}
class D{
int i;
}
public class NullPointerTest{
public static void main(String[] args){
Customer c = new Customer();
System.out.println(c.id);
c.id = 9876;
System.out.println(c.id);
c = null;//编译器只检查语法。语法没错。
System.out.println(c.id);
}
}
class Customer{
int id;
}
关于垃圾回收器GC:在Java中,垃圾回收期主要针对的是堆内存。当一个Java对象没有任何引用指向该对象时,GC会考虑将该垃圾数据释放回收掉。
空引用访问实例(对象相关)相关的数据时都会出现空指针异常。
public class Test{
public static void main(String[] args){
int i = 10;
add(i);
System.out.println("main-->"+i);
}
public static void add(int i){
i++;
System.out.println("add->"+i);
}
}
- 无论是基本数据类型还是引用数据类型传值都是值传递
public class Test{
public static void main(String[] args){
Person p = new Person();
p.age = 10;
add(p);
System.out.println("main->"+p.age);
}
public static void add(Person p){
p.age++
System.out.println("add->"+p.age);
}
}
class Person{
int age;
}
值传递传递的是变量中保存的值复制一份传递过去。
构造方法:通过构造方法可以完成对象的创建以及实例变量初始化。也就是说,构造方法是用来创建对象并且同时给对象的属性赋值。
当一个类没有提供任何构造方法,系统默认提供一个无参构造方法。
建议将无参构造写出来。
调用构造方法使用new运算符
// 构造方法语法: [修饰符列表]构造方法名(形式参数列表){ 构造方法体; } 修饰符目前统一写public 构造方法与类名必须一致。 构造方法不需要指定返回值类型,也不能写void。写void表示普通方法。 //普通方法语法: [修饰符列表]返回值类型 方法名(形式参数列表){ 方法体; } //构造对象 new 构造方法名(参数列表);
-
public class ConstructorTest{ public static void main(String[] args){ Student s1 = new Student(); //如果定义了一个有参构造,则系统不会提供无参构造方法。 System.out.println(s1); Student s2 = new Student(2); Student s3 = new Student(1,"11",12); System.out.println(s3.id); System.out.println(s3.name); System.out.println(s3.age); } public static void doSome(){ System.out.println("111"); } }
public class Student{ int id; string name; int age; public Student(){ System.out.println("do some!"); } public Student(int i){ } public Student(String name){ } public Student(int id,String name,int age){ id = id; name = name; age = age; } }
成员变量默认赋值的时机:在构造方法执行的过程中完成的初始化。
构造方法:用于对象的创建
封装作用:保证内部结构的安全;屏蔽复杂,暴露简单。
-
在代码级别上,封装有什么用?
一个类中的数据,假设封装之后,对于代码的调用人员来说,不需要关心代码的复杂实现,只需要通过一个简单的入口就可以访问了,另外,类体重安全级别较高的数据封装起来,外部人员不能随意访问,来保证数据的安全性。
public class Person{ int age; }
public class PersonTest{ public static void main(String[] args){ Person p1 = new Person(); System.out.println(p1.age); p1.age = 50; System.out.println(p1.age); p1.age = -100;//age是一个负数,但是通过了。 System.out.println(p1.age); } }
//不使用封装Person类的age暴露,随意修改。
//封装起来,数据安全,调用方便 //属性私有化,对外提供简单的操作 public class PersonTest{ public static void main(String[] args){ Person p1 = new Person(); System.out.println(p1.age); p1.age = 50; System.out.println(p1.age); p1.age = -100;//age是一个负数,但是通过了。 System.out.println(p1.age); } }
public class Person{ private int age;//只能在本类中访问,出来就不能访问了。 //外部访问入口 }
构造方法作用:创建对象,给属性赋值。
public class MethodTest{
public static void main(String[] args){
//调用static的调用方法
MethodTest.doSome();
doSome();
//不带static的调用方法
MethocTest mt = new MethodTest();
mt.doOther();
}
//带static方法
public static void doSome(){
System.out.println("wss");
}
//无static方法,实例方法,必须通过对象调用
public void doOther(){
}
}
//空指针异常本质是空引用访问实例相关数据。
public class NullPointerTest{
public static void main(String[] args){
User u = new User();
System.out.println(u.id);
u.doSome();
u = null;
System.out.println(u.id);//需要对象存在,空指针异常
u.doSome();//一个实例方法调用必须有对象的存在,所以空指针异常。
}
}
class User{
int id;
public void doSome(){
System.out.println("dosome");
}
public void exam(){
}
}
public class Person{ private int age;//只能在本类中访问,出来就不能访问了。 //外部访问入口 //提供对外公开的入口,都是类的实例操作入口,因此非static类型的。 //set和get的格式: //public 返回值类型 get+属性首字母大写(无参){ return xxx; //} //public void set+属性首字母大写(参数){ xxx = 参数; //} public int getAge(){ return age; } public void setAge(int nianLing){ if(nianLing < 0 || nianLing > 150){ System.out.println("年龄值不合法"); return; } age = nianLing; } }
public class PersonTest{
public static void main(String[] args){
Person p = new Person();
int nianLing = p1.getAge();
System.out.println(nianLing);
p1.setAge(100);
System.out.println(p1.getAge());
p1.setAge(-100);
System.out.println(p1.getAge());
}
}
- 封装的代码实现:属性私有化;对外提供set和get方法。
- set和get都是实例方法,不带static,实例方法必须先new对象。