数据类型
8大基本数据类型
- 数字类型
- 整数:默认值为0
- byte
- short
- int(推荐,默认类型,10)
- long
- 小数:默认值为0.0
- float
- double(推荐,默认类型,10.0)
- 整数:默认值为0
- 字符类型
- char
- 布尔类型
- boolean(推荐,默认类型,10.0)
true/false:默认值是false
- boolean(推荐,默认类型,10.0)
引用类型
- 字符串类型:String
类与对象
在程序中对事物的描述与该事物在现实中的形态保持一致。为了做到这一点,面向对象的思想中提出两个概念,即类和对象。
1 类的定义
类是对某一类事物的抽象描述。
2 对象的定义
对象用于表示现实中该类事物的个体。
面向对象三大特征
封装
- 只隐藏对象的属性和实现细节,仅对外提供公共访问方式
- 好处: 将变化隔离、便于使用、提高复用性、提高安全性
- 原则:将不需要对外提供的内容隐藏起来;把属性隐藏,提供公共方法对其访问
封装的步骤
- 第1步:属性私有化(访问修饰符改为private)
- 第2步:为属性添加公共方法对外提供访问
getter/setter方法 - 第3步:根据需要加入业务逻辑控制语句
访问修饰符
修饰符 | 同一个类中 | 同一个包中 | 不同包的子类中 | 任何地方 |
---|---|---|---|---|
private | Y | N | N | N |
默认修饰符 | Y | Y | N | N |
protected | Y | Y | Y | N |
public | Y | Y | Y | Y |
普通方法
普通方法的语法
[访问修饰符] 返回值类型 方法名([参数列表]){
// 方法体 coding...
}
public void setAge(int age){
// 方法体 coding...
}
public int getAge(){
// 方法体 coding...
}
构造方法
实例化对象调用构造方法
new 类名()
构造方法的语法
public class 类名{
// 构造方法
public 类名(){
}
}
构造方法的规则
- 构造方法名和类名相同
- 构造方法没有返回值的特殊方法
// 普通方法 [访问修饰符] 方法名([参数列表]){ // 方法体 coding... } public class 类名{ // 构造方法 public 类名(){ } }
- 如果没有手动显示的创建构造方法,那么JVM会为我们默认创建1个无参的构造方法。
- 如果手动显示的创建了构造方法
- 那么JVM为我们默认创建的无参构造方法就没有了。
- 有哪些参数的构造方法就能调用哪些
构造方法的作用
- 实例化对象
- 通过构造方法来进行属性的传参设值
子类继承父类时通过构造传参
- 调用父类的构造方法是通过super调用父类的构造方法实现
-
super()构造方法只能出现在构造方法的第一行
-
如果没有显示的使用super()调用父类的构造方法时,JVM会默认调用父类的无参构造方法
-
-
可以自由选择调用哪个父类的构造方法
this和super关键字
-
this:表示当前对象,在类的内部使用
// 调用成员属性 this.courseName = courseName; // 调用成员方法 this.getCourseName();
-
super:表示父类
// 调用的父类的成员属性 super.test1 = "这是测试数据"; // 调用父类的成员方法 super.setName("测试数据");
继承
继承的特点
-
子类自动拥有父类非私有的属性与方法。
-
提高代码复用性;继承是多态的前提。
继承的步骤
-
第1步:将共同的属性和方法抽取出来往上提一级放到父类中
-
第2步:子类通过extends关键字继承父类
package com.tipdm.demo1; public class Person { // 共有的属性 private String name; private String gender; private int age; // 省略setter/getter方法 }
public class Student extends Person{ // private String name; // private String gender; // private int age; // 特有的属性 private String className; // 省略setter/getter方法 } public class Teacher extends Person{ // private String name; // private String gender; // private int age; // 特有的属性 private String courseName; // 省略setter/getter方法 }
- 第3步:实例化子类时,可以使用父类中非私有的属性和方法
static关键字
static修饰的属性和方法都可以通过类名.
的方式访问,是否能访问属性和方法取决于访问修饰符是否可见。
-
静态属性:static修饰的属性,所有对象实例共享相同的值
类名.属性名
-
静态方法:static修饰方法
类名.方法名()
-
使用static修饰的方法只能调用static修饰的方法,不能调用普通方法(no-static)和普通属性(no-static)
public class Person { String name; // static修饰的属性,所有对象实例共享该值 public static int age; public void print(){ } public static void print2(){ System.out.println(age); // 静态方法不能调用非静态的属性和方法 // System.out.println(name);// 报错 // print();// 报错 } }
-
非静态方法可以调用静态方法和静态属性
多态
-
-
类的多种形态。是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。
-
好处:提高了程序的扩展性。
-
弊端:当父类引用指向子类对象时,虽提高了扩展性,但只能访问父类中具备的方法,不可访问子类中的方法;即访问的局限性。
-
前提:实现或继承关系;覆写父类方法
多态的几种表现形式
-
第一种表现形式:方法的重载或重写
-
重载
- 在同一个类中
- 方法名相同
- 参数列表的类型和个数不同
- 与访问修饰符和返回值类型无关
// 整数的加法 public int add(int a,int b){ return a+b; } // 浮点数的加法 public double add(double a, double b, double c){ return a+b+c; }
-
重写
-
子类重写父类的方法
-
方法名和参数列表的类型和个数都要求相同
-
访问修饰符不能严于父类
-
返回值类型和父类相同或者是其子类
public class Person { // 父类声明的方法 protected Person getInstance(Person person){ return null; } } public class Student extends Person { @Override public Student getInstance(Person person) { // 子类重写父类的方法,在子类中完成自己特有的业务代码 return null; } }
-
-
-
第二种表现形式:
-
向上转型
// 向上转型:从子类向父类自动转型 Person person = student;
-
向下转型
Student student = new Student(); Person person = student; // 向下转型:默认编译器会报错 // 解决:需要强制类型转换 // 强制类型转换时可能会抛出异常:ClassCastException Student stu2 = (Student) person; System.out.println(stu2); System.out.println("----------------"); Person person2 = new Teacher(); System.out.println("person2:"+person2); // 向下转型 // 会抛出异常,因为person2的实际类型是Teacher类型,不是Student类型 Student stu3 = (Student)person2;
-
常用的条件语句和循环语句
条件语句
-
if:判断语句
-
基本判断语句:
if(条件){// 条件为true时执行 // code }
-
多条件判断
if(条件1){// 条件为true时执行 } [else if(条件2){ }] [else if(条件3){ }] // else if:可以写0到多个 [else{ // 以上所有条件都不满足时执行 }]
-
-
switch()
循环语句
-
do while/while
当我知道循环次数时使用这种
-
while:先条件决断是否允许执行循环,可能一次也不会执行,可能会执行多次。
while(条件){ // code }
-
do…while:先执行代码块,再进行条件判断。至少执行一次。
do{ // code }while(条件);
-
-
for
当知道循环次数时使用这种
// 表达式1:数据初始化 // 表达式2:条件判断,符合条件时继续执行循环体 // 表达式3:自增或自减 for(表达式1;表达式2;表达式3){ // 循环体 } // 示例:输出1-5之间数字 // 表达式1:初始化变量i=1 // 表达式2:条件判断-如果i<=5时执行循环体的内容 // 表达式3:i=i+1 for(int i=1;i<=5;i++){ System.out.println(i); }
for语句执行顺序:
- 第1步:执行表达式1
- 第2步:执行表达式2
- 第3步:条件判断
- 如果条件为true,执行循环体的代码
- 如果条件为false,则跳出循环
- 第4步:执行表达式3
- 第5步:重复执行第2步到第4步
抽象类
什么时候将方法声明为抽象方法
当父类中抽取的方法不确定实现的方法体内容或实现的内容无意义时可以将方法声明为抽象方法。
抽象类和抽象方法的定义
-
抽象类的定义
// 使用abstract关键字修饰类 public abstract class 类名{ }
-
抽象方法的定义
// 将父类中的普通方法变成抽象方法 // 1) 没有方法体 // 2) 方法使用abstract关键字修饰 public abstract void 方法名;
示例
# 1.交通工具类:Vehicle
package com.tipdm.demo4;
public abstract class Vehicle {
// 将父类中的普通方法变成抽象方法
// 1) 没有方法体
// 2) 方法使用abstract关键修饰
public abstract void run();
}
# 2.子类-公共汽车类Bus
public class Bus extends Vehicle{
@Override
public void run() {
// super.run();// 调用父类的成员方法
System.out.println(this.getType()+"在马路上行驶...");
}
}
# 3.子类-轮船类Ship
public class Ship extends Vehicle {
@Override
public void run() {
System.out.println(this.getType()+"在海洋中行驶...");
}
}
# 4.测试类
public class Test {
public static void main(String[] args) {
// 公共汽车
Bus bus = new Bus("公共汽车", "白色", 4);
System.out.println(bus);
// 调用行驶的方式
bus.run();
System.out.println("-----------------------");
// 轮船
Ship ship = new Ship("轮船","黑色");
System.out.println(ship);
// 调用轮船的行驶的方式
ship.run();
System.out.println("------------------------");
// 卡车
Truck truck = new Truck("卡车", "绿色", 8);
System.out.println(truck);
truck.run();
}
}
抽象类的特点
-
抽象类和抽象方法都需要被 abstract 修饰。抽象方法一定要定义在抽象类中。
-
抽象类不可以直接创建对象,原因:调用抽象方法没有意义。
-
抽象类中包含普通方法和抽象方法,可以不定义抽象方法。
# 1.同时有普通方法和抽象方法
# 2.普通方法和抽象方法都没有
# 3.只有普通方法,没有抽象方法
- 只有覆盖了抽象类中所有的抽象方法后,其子类才可以创建对象。否则该子类还是一个抽象类。
零散小结:
1)String.subString()的使用
2)数组中的length是属性,字符串的length()是方法;
3)为什么不建议写str += n + “,”;?
因为放入循环后会占内存;
4)抽象方法:
抽象方法避免了无意义代码的编写,抽象方法是为了给子类重写的。抽象方法必须在抽象类中,抽象类中可以没有抽象方法。
5)抽象类
抽象类不能实例化(所以出现父类的引用指向子类的实例的操作)
父类是抽象类,则该子类必须重写所有抽象方法,否则子类必须是抽象类;
6)重写构造方法时最好把无参构造方法写上,由于Java的放射机制需要用到。