2.面向对象
-
面向对象(Object-Oriented)
- ooa:面向对象的分析
- ood:面向对象的设计
- oop:面向对象的编程
-
面向对象三大特性
- 封装,继承,多态
2.1类和对象关系
-
类:一种数据类型,引用数据类型,自定义的一种类型,用变量表示属性,用方法表示行为
-
对象:具体存在的事务,符合类的定义特征.
-
类的定义个数:
class 类名[]
-
如何创建对象
类名 对象名 = new 类名();
-
demo1:创建一个学生类定义姓名,性别,分数,定义一个方法study添加一个自我介绍的方法。
// StudentDemo package obj; public class Student { String name; int age; double score; // 定义方法 public void teach() { System.out.println("姓名:" + this.name); } } // TestDemo package obj; public class StudentDemo { public static void main(String[] args) { Student std = new Student(); std.name = "小明"; std.age = 12; std.score = 80; System.out.println(std);// obj.Student@4c203ea1 System.out.println(std.name);// 小明 std.teach();// 姓名:小明 } }
2.2组件介绍
- 成员变量,静态变量,局部变量,成员方法,静态方法,构造方法
package obj;
public class Student {
// 成员变量
String name;
int age;
double score;
// 静态变量
static int a;
// 成员方法
public void teach() {
System.out.println("姓名:" + this.name);
}
// 静态方法
public static void test(int x, int y) {
int abc = 100;//局部变量
}
// 构造方法
public Student(String name , int age) {
this.name = name;
this.age = age;
}
}
- 六大组件总结
成员变量: 类中方法外,没有static修饰,存放在堆内存中,有初始值,随着对象的创建而产生,随着对象的消失而消失。
静态变量: 类中的方法外,有static修饰,存放在方法区的静态区,有初始值,随着类的加载而加载,随着类的消失而消失
局部变量: 定义在方法中或方法的参数列表上,存在栈内存中,没有初始值,随着方法的调用而创建,随着方法的结束而消失。
成员方法:没有static修饰的方法,使用对象调用。
静态方法:有static修饰的方法,使用类名调用
构造方法: 方法名和类名相同,没有返回值。使用new 关键字创建对象的时候调用。
2.3面向对象内存分配
// 解析
当我们创建一个类时候,首先会在堆空间方法去创建class区和static区。class区保存定义的类,static保存静态方法。当我们对类进行初始化,class区将成员变量初始化并拷贝到堆内存地址中,初始化变量指向类方法内定义成员变量的地址。
2.4成员变量和局部变量区别
- 成员变量:定义在类中方法外,没有static修饰,存储在堆内存中,有初始值,随着对象的消失而消失。
- 局部变量:定义在方法中或者方法的参数列表上,存储在栈内存中,没有初始值,随着方法的调用而产生,随着方法的结束而消失。
2.5 封装
-
封装前需要使用成员变量:private. 此为权限修饰符,当然权限修饰符还有:public,protected,default,private。
-
而private表示私有的,它可以修饰方法和变量,被private修饰符方法和变量,只能在本类种访问:
-
提供一套访问的修饰方法get和set方法。
-
demo
// Teacher类
package func;
public class Teacher {
private String name;
private int age;
private int gender;
private double salary;
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;
}
public int getGender() {
return gender;
}
public void setGender(int gender) {
this.gender = gender;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void show() {
System.out.println("name:" + name + "age:"+ age+ "gender:" + gender + "salary:" + salary);
}
}
// 调用封装Teacher类
package func;
public class TeacherDemo {
public static void main(String[] args) {
Teacher t = new Teacher();
t.setName("张三");
t.setAge(18);
t.setGender(1);
t.setSalary(1235.3);
t.show();
}
}
- 封装练习
package func;
public class Mobile {
private String brand;
private String type;
private double price;
private String color;
public void setBrand(String brand) {
this.brand = brand;
}
public void setType(String type) {
this.type = type;
}
public void setPrice(double price) {
this.price = price;
}
public void setColor(String color) {
this.color = color;
}
public String getBrand() {
return brand;
}
public String getType() {
return type;
}
public double getPrice() {
return price;
}
public String getColor() {
return color;
}
public void show() {
System.out.println("brand:"+brand+"color:"+color+"type:"+type+"price:"+price);
}
}
package func;
public class MobileDemo {
public static void main(String[] args) {
Mobile m1 = new Mobile();
m1.setBrand("华为");
m1.setColor("红色");
m1.setType("5G");
m1.setPrice(2399.5);
Mobile m2 = new Mobile();
m2.setBrand("苹果");
m2.setColor("黄色");
m2.setType("X");
m2.setPrice(4399.5);
Mobile[] ms = new Mobile[] {m1, m2};
for (int i=0;i<ms.length;i++) {
ms[i].show();
}
}
}
- 练习求长方形周长和面积
package func;
public class Rect {
private double length;
private double width;
public void setLength(double length) {
this.length = length;
}
public void setWidth(double width) {
this.width = width;
}
public double periMeter() {
return 2*(this.length+this.width);
}
public double area() {
return this.length*this.width;
}
}
package func;
public class RectDemo {
public static void main(String[] args) {
Rect r = new Rect();
r.setLength(10);
r.setWidth(5);
double perimeter = r.periMeter();
double area = r.area();
System.out.println(perimeter);// 30.0
System.out.println(area);// 50.0
}
}
2.6构造方法
- 当new的时候,构造方法被调用,构造方法没有返回值,构造方法名与类名相同,构造方法可以被重载(一个类中可以存在多个名字相同的方法,但是必须保证参数的个数或类型不同,与返回值无关)。
- 如果我们没有在类种写构造方法,系统会默认为我们生成一个无参数的构造方法,如果我们写了构造方法,则系统不会为我们生成默认构造方法。
package gouzao;
public class Teacher {
private String name;
private int age;
private double salary;
public Teacher(String name, int age, double salary) {
this.name = name;
this.age = age;
this.salary = salary;
}
public void show() {
System.out.println("name:"+name+"age:"+age+"salary:"+salary);
}
}
package gouzao;
public class TeacherDemo {
public static void main(String[] args) {
Teacher t = new Teacher("Tom",20,25002.3);
t.show();
}
}
- 生成get/set无参数方法:eclipse-->右键--->Source--->Generate getters nad setters
2.7类的三种赋值方式:
1.
Product p1 = new Product();
p1.proId = "001";
p1.proName = "毛巾";
p1.proPrice = 1234;
p1.proNum = 90;
2.
Product p2 = new Product();
p2.setProId("002");
p2.setProName("馒头");
p2.setProPrice(10);
p2.setProNum(70);
3.
Product p3 = new Product("003", "袜子", 10, 20);
2.7同名局部变量和成员变量的区分
package demo;
public class Person {
// 成员变量
String name = "张三";
// 方法的重载:
public void print() {
System.out.println(name);
}
public void print(String name) {// 就近原则调用name
System.out.println(name);
}
public void print1(String name) {
System.out.println(this.name);
}
public static void main(String[] args) {
Person p = new Person();
System.out.println(p.name);// 张三
p.name = "李四";
p.print();// 李四
p.print("老刘");// 老刘
p.print1("小明");// 李四
}
}
2.8 static关键字
- 类中成员方法和成员变量使用对象调用,类中的静态方法和静态变量使用类名调用。类中构造方法是使用new关键字创建对象调用。
package demo;
public class Student {
String name;
int age;
public Student(int a) {
System.out.println(a);
}
public void study() {
System.out.println("好好学习天天向上!");
}
public static void test() {
System.out.println("test 静态方法!");
}
}
package demo;
public class StudentDemo {
public static void main(String[] args) {
// 构造方法通过new调用
Student s = new Student(123);
// 成员方法,成员方法用类对象.方法
s.study();
// 静态方法用类.方法调用
Student.test();
new Stidemt(777).study();// 匿名对象,只用于调用1次情况下
// 局部变量只能在方法中使用.
}
}
- 静态方法无法使用成员变量,只能调用静态变量。
因为成员变量是通过new对象才能产生,而调用静态方法,没有new对象,所以无法调用
- 静态变量与非静态变量区别
成员变量可以理解为,每当你new一个对象都会在堆中新生成一个或多个新的成员变量。
静态变量,相当于所有对象都共用这一套静态变量,它属于类的。
2.9代码块
-
静态代码块:static{}
执行周期:随着类的加载而执行一次
- demo
package demo; public class CodeBlockDemo { static { System.out.println("打印静态代码块"); } public static void main(String[] args) { } }
-
构造代码块:{}
每new 关键字创建一个对象,就会执行一次
- demo
{ System.out.println("构造代码块"); } public static void main(String[] args) { CodeBlockDemo c1 = new CodeBlockDemo(); CodeBlockDemo c2 = new CodeBlockDemo(); } // 构造代码块 // 构造代码块
-
构造方法代码块:
public class CodeBlockDemo { static { System.out.println("打印静态代码块"); } { System.out.println("构造代码块"); } public CodeBlockDemo() { System.out.println("构造方法代码块"); } public static void main(String[] args) { CodeBlockDemo c1 = new CodeBlockDemo(); CodeBlockDemo c2 = new CodeBlockDemo(); } } // 打印静态代码块 // 构造代码块 // 构造方法代码块 // 构造代码块 // 构造方法代码块
- 由上面可以看出:静态代码块 先于 构造代码块 先于 构造方法。
-
局部代码块
- 定义在方法中的代码块,运行完后立刻释放。
package demo; public class CodeBlockDemo { public void show() { { System.out.println("局部代码块"); } } public static void main(String[] args) { new CodeBlockDemo().show(); } }
-
练习:统计创建对象的总个数:
package demo; public class CodeBlockDemo { static int count = 0; static { System.out.println("打印静态代码块"); } { count++; System.out.println("构造代码块"); } public CodeBlockDemo() { System.out.println("构造方法代码块"); } public void show() { { System.out.println("局部代码块"); } } public static void main(String[] args) { CodeBlockDemo c1 = new CodeBlockDemo(); CodeBlockDemo c2 = new CodeBlockDemo(); new CodeBlockDemo().show(); System.out.println(count);// 3 } }