一.类的提炼过程
-
从现实生活中归纳总结出,多种相同物种,具有的相同的特性(属性+行为)提炼到一个容器里,给这个容器起一个名字,名字就是类。
-
步骤:
-
发现类(Dog)
-
发现类的属性(毛色,品种,姓名,年龄等)
-
发现类的方法(跑,叫等)
二.类图
-
我们可以使用类图描述类,进而来分析和设计类。
-
使用类图描述类更加的形象和直观。
- 类的形成
package lianxi;public class Dog {
//属性public String brand;public String name;public int age;//行为:方法public void run(){System.out.println("run");}public void bark(){System.out.println("bark");}
}
ps:图截取自视频老师讲解。在实际开发中,需求在需求文档中,需求文档一般都是文字描述的需求,从文字中提炼有效信息,将有效信息先设计成类图,然后再定义类。
三.构造方法
- 构造方法主要完成对象的创建工作。
- 基础语法
访问修饰符 构造方法名(){
//初始化代码
}
系统提供默认无参构造方法
public Dog(){
}
package lianxi;
//Dog类
public class Dog {
//属性public String brand;public String name;public String age;//构造方法:无参构造//我们自己定义了任何一款构造函数,那么系统都不再帮我们生成任何构造了。public Dog(){// System.out.println("1111");}//行为:方法public void run(){System.out.println("run");}public void bark(){System.out.println("bark");}public void show(){System.out.println("品种是:"+brand+",姓名是:"+name+",年龄是:"+age);}
}
package lianxi;public class To1 {public static void main(String[] args) {//1.本质上调用了无参构造方法.//2.构造方法可以创建对象。//3.手动写了构造,系统不会再提供构造。Dog dog = new Dog();dog.brand="柯基";dog.name="旺财";dog.age="3";dog.show();}
}
ps:较为复杂,写代码较慢,可用带参构造进行优化。
-
自定义构造方法
- 构造方法和类名相同。
- 没有返回值。
- 注意:一旦自定义构造方法,系统将不再提供默认的构造方法。
ag:Dog dog = new Dog("柯基","旺财",3);
package lianxi;
//Dog类
public class Dog {
//属性public String brand;public String name;public int age;//构造方法:无参构造//我们自己定义了任何一款构造函数,那么系统都不再帮我们生成任何构造了。/** public Dog(){System.out.println("1111");}*///构造方法不能有任何任何放回类型,甚至连void都不能有。public Dog(String bread,String name,int age){//this后面跟的是成员变量
this.brand = bread;
this.name = name;
this.age = age;}
public Dog(String brand,String name){this.brand = brand;this.name = name;
}
public Dog(String brand){this.brand = brand;
}//行为:方法public void run(){System.out.println("run");}public void bark(){System.out.println("bark");}public void show(){System.out.println("品种是:"+brand+",姓名是:"+name+",年龄是:"+age);}
}
package lianxi;public class To1 {public static void main(String[] args) {//1.本质上调用了无参构造方法.//2.构造方法可以创建对象。//3.手动写了构造,系统不会再提供构造。
// Dog dog = new Dog();
// dog.brand="柯基";
// dog.name="旺财";
// dog.age= 3;
// dog.show();Dog dog = new Dog("柯基","旺财",3);dog.show();}
}
ps:如此一来main函数中只用两行代码就解决了。
-
方法重载
- 方法名相同,实现的功能相同。
- 参数列表不同:参数类型、参数个数、参数顺序不同
- 与返回值和访问修饰符无关。
ps:普通方法可以实现重载,构造方法也可以重载。
public void test(String name,int num){}public void test(int num,String name){}
int test(String name,int num){return num;}public void test(int num,String name){}
四.static的使用
- 直接使用static修饰属性和方法
package lianxi;public class Cat {
static String name;
public static void show() {System.out.println("1");
}
}
package lianxi;public class T02 {public static void main(String[] args) {Cat.name = "小猫";Cat.show();}
}
ps:静态的变量是斜着的。静态成员占用的内存是静态存储区,而且一个成员一旦变成静态的,它就是类本身所有,只有一份,和对象就没有关系了。它会一直生存到程序结束。占用内存空间很大。所以不能把所有变量都定义成静态的。
-
static代码块
-
JVM加载类时,加载静态代码块。
-
如果有多个静态块,按顺序加载。
-
每个静态代码块只会被执行一次。
package lianxi;public class StaticTest {static int num=100;static {num+=100;System.out.println(num);}static{num+=500;System.out.println(num);}
}
package lianxi;public class T03 {public static void main(String[] args) {StaticTest st1 = new StaticTest();//由于类只会被加载一次,所有静态成员也只被加载一次。StaticTest st2 = new StaticTest();System.out.println(StaticTest.num);}
}
-
static变量
-类变量(静态变量)
-
被static修饰的变量
-
在内存中只有一个拷贝
-
类内部,可在任何方法内直接访问静态变量
-
其他类中,可以直接通过类名访问了
-实例变量
-
没有被static修饰的变量
-
每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响
-
static方法
-静态方法:可直接通过类名访问
- 不能直接访问所属类的实例变量和实例方法
- 可直接访问类的静态变量和静态方法
-实例方法:通过实例访问
- 可直接访问所属类的静态变量、静态方法、实例变量和实例方法
五、封装
封装的理解
-
封装是面向对象的三大特性之一
-
封装:将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问
-
封装的优点:
-
隐藏类的实现细节
-
只能通过规定方法访问数据
封装的过程
-
将属性的可见性设为private
-
创建公有的getter和setter方法
-
在getter和setter方法中加入判断语句
package lian;public class Dog {//public privateprivate String name;private int age;//alt+enter快捷键//给出一个访问方式//两个方法:都是公开的public//赋值public void setName(String name) {this.name = name;}//取值public String getName() {return name;}public int getAge() {return age;}public void setAge(int age) {if (age < 0) {//非法年龄age = 0;} else {this.age = age;}}
}
package lian;public class T05 {public static void main(String[] args) {Dog dog = new Dog();dog.setName("小黑");String name = dog.getName();System.out.println(name);dog.setAge(-100);System.out.println(dog.getAge());}
}
封装的两种体现
-
一个类中可以出现成员变量和成员方法
-
将私有的成员变量封装成公有的get和set方法。
六、this用法
- 当参数名称和成员名称相同时,可以使用this关键字表示成员变量
七、导入包
- 为了使用不在同一包中的类,需要在Java程序中使用import关键字导入这个类
- import 包名.类名
导入包的注意事项
- 一个类同时引用了两个来自不同包的同名类
-必须通过完整类名来区分
- package和import的顺序是固定的
-
package必须位于第一行
-
只允许有一个package语句
-
其次是import
-
接着是类的声明
八、访问控制
-
类的访问控制
-public修饰符:公有访问级别
-默认修饰符:包级私有访问级别
-
类成员的访问控制
作用域 修饰符 | 同一个类中 | 同一个包中 | 子类中 | 任何地方 |
private | 可以 | 不可以 | 不可以 | 不可以 |
默认修饰符 | 可以 | 可以 | 不可以 | 不可以 |
protected | 可以 | 可以 | 可以 | 不可以 |
public | 可以 | 可以 | 可以 | 可以 |
练习一
- 运用面向对象的思想抽象出Car类,汽车有品牌,型号,生产年份,行驶里程数,对行驶里程数进行封装,保证数据的有效性。使用带参构造对属性赋值。
package lian;public class Car {//品牌String brand;//型号String model;//生产年龄int year;//行驶里程数private int mile;public Car(String brand, String model, int year) {this.brand = brand;this.model = model;this.year = year;}public int getMile() {return mile;}public void setMile(int mile) {if (mile<0){//证明行驶的公里数是0mile=0;}else {this.mile = mile;}}public void show(){System.out.println("汽车的品牌为:"+brand+",汽车的型号为:"+model+",汽车的生产年份为:"+year+",汽车的行驶里程数为:"+mile);}
}
package lian;public class T06 {public static void main(String[] args) {Car car = new Car("迈巴赫","S680",2023);car.setMile(-100);car.show();}
}
练习二
- 模拟实现投票过程:每个网民只允许投一次票,并且当投票总数达到1000时,就停止投票。
package lian;public class Vote {//投票的次数static int count;public static final int MAX_COUNT = 1000;public String name;public Vote(String name){this.name=name;}//投票的方法public void voter(){//如果投票到达了上限,就提醒投票结束if (count==MAX_COUNT){System.out.println("活动已结束,停止投票");}else {count++;System.out.println("感谢"+name+"投票");}}public static void show(){System.out.println("目前"+count+"票");}
}
package lian;public class T07 {public static void main(String[] args) {Vote vote = new Vote("张三");Vote vote1 = new Vote("李四");Vote.show();vote.voter();vote1.voter();Vote.show();}
}
九、笔记
-
Ctrl+鼠标左键,可以在idea中转到相应的定义。
-
方法重载:overload。