一.类的提炼过程
-
从现实生活中归纳总结出,多种相同物种,具有的相同的特性(属性+行为)提炼到一个容器里,给这个容器起一个名字,名字就是类。
-
步骤:
-
发现类(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 private
private 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){//证明行驶的公里数是0
mile=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。