Java三大特性
1、继承
1.1、定义类
通过class关键字定义类
[访问修饰符] class 类名 {
属性1;
属性2;
......
方法1;
方法2;
.......
}
类和对象的关系:类是抽象的,泛指所有对象类型;对象是具体的,就是具体的某个对象
1.2、定义属性
语法格式:【访问修饰符】 数据类型 属性名;
注意:属性必须写在类里
1.3、定义方法
1.4、访问修饰符
public:公开的
private:私有的
1.5、new关键字
语法格式: 类名 对象名 = new 类名();
注意:new关键字可以创建类的对象
所有对象都是引用数据类型,存储的不是值,而是地址
1.6、对象操作属性
- 通过对象为属性赋值:对象名.属性名 = 值;
- 通过对象获取属性的值:对象名.属性名;
1.7、对象调用方法
1.8、this关键字
- 方法里面可以写this,代表当前对象。
- 这个当前对象就是代表该方法谁调用的,就是谁
1.9、static关键字
1.10、构造方法
-
语法: 【访问修饰符】 类名([参数列表]) {}
-
作用:1、创建类的对象; 2、初始化对象的一些属性
-
构造方法有2种:无参构造方法、有参构造方法
public class Computer { //计算机属性 public String type;//计算机型号 public int card;//计算机显卡 public String cpuType;//计算机cpu型号 public String syst;//计算机系统 public String chip;//计算机芯片 public int internal;// 计算机内存 public double display;// 计算机显示器 } class ComputerTest{ public static void main(String[] args) { //创建一个计算机对象 //1、无参构造方法 Computer computer1=new Computer(); System.out.println("第一台计算机型号是:"+computer1.type); System.out.println("第一台计算机显卡是:"+computer1.card); System.out.println("第一台计算机生产商是:"+computer1.cpuType); System.out.println("第一台计算机系统是:"+computer1.syst); System.out.println("第一台计算机主板是:"+computer1.chip); System.out.println("第一台计算机内存是:"+computer1.internal); System.out.println("第一台计算机显示器是:"+computer1.display); System.out.println("----------*-----------"); //2、有参构造方法 Computer computer2=new Computer("魔霸6",6,"AMD 锐龙6000系旗舰锐龙6","Win10","NVIDA GeForce RTX 3060",16,15.6);
1.10、方法的重载
public class Student { //引用数据类型默认值都为null public String name; public int age; //是重写在Object类里面的 //重写就是子类覆盖父类的词名方法 @Override//注解:告诉编译器我确实是重写了父类的toString public String toString() {//这样main方法里的 System.out.println(stu);不在打印的是stu地址了 return "学生的信息是【" + "name='" + name + '\'' + ", age=" + age + '】'; } class StudentTest{ public static void main(String[] args) { Student stu=new Student(); stu.name="叶孤城"; stu.setAge(-20);//写 //获取年龄 int a=stu.getAge();//读 System.out.println("该学生的年龄"+a);//打印出来的是0,因为写-20值判断年龄不能为负,所以为默认值0 System.out.println("该学生的姓名"+stu.name); //打印的是stu的地址 System.out.println(stu);
1.11、属性私有化,利用set get读写
public class Student { // int类型的属性默认值是0 private int age; // 年龄 // 引用数据类型默认值都是null public String name; // 名称 // 。。。。。 // 提供写方法setter - > 写 // AOP 把这一块逻辑专门切分出来,动态代理,在运行的时候,动态插入一段代码 public void setAge(int age) { if (age < 0) { System.out.println("对不起年龄不能为负数!"); } else { this.age = age; } } // 提供写方法getter - > 读 // getter + setter public int getAge() { return this.age; } }
1.12、数组存储Student对象
public class Student2 { public int age; public String name; public Student2(int age, String name) { this.age=age; this.name=name; } //读 public void setAge(int age){ this.age=age; } //写 public int getAge(){ return age; } public void setName(String name){ this.name=name; } public String getName() { return name; } } class StudentTest2{ public static void main(String[] args) { //存储一组数字 int a=10; int[] nums={}; //存储一组字符串 String n="aaa"; String[] name={}; //存储一组学生 //类就是该对象的类型【stu的类型就是Student2】 Student2 stu1=new Student2(20,"叶孤城"); Student2 stu2=new Student2(22,"张三"); Student2 stu3=new Student2(23,"李四"); //对象数组【该数组名为stu的类型就是Student2】 Student2[] stus={stu1,stu2,stu3}; //遍历数组 System.out.println("-----------遍历数组-----------"); for (int i = 0; i < stus.length; i++) { System.out.println(stus[i].getAge()+"\t"+stus[i].getName()); } for (Student2 student2:stus) { System.out.println(student2.getAge()+"\t"+student2.getName()); } } }
1.13、包装类
java中的8个基本数据类型,都有一个对应的引用数据类型
1.14、装箱和拆箱的概念
public class Test2 {
public static void main(String[] args) {
//str是引用数据类型
String str = "abc";
//i是基本数据类型
int i = 10;
//b是引用数据类型
Integer b = 20;
System.out.println(b);
//基本数据类型转成对应的引用数据类型【包装】
int n = 10;
Integer num = n;//整型
double d = 1.78;
Double D=d;//浮点型
char c = '女';
Character C = c;//字符型
boolean r = true;
Boolean R = r;//布尔型
//装箱:把int n 往Integer num转
//拆箱:把Integer num 往int n转
//字符串转成Integer
String str3 = "123";
Integer num3 = Integer.valueOf(str3);
//字符串转成int
int num4 = Integer.parseInt(str3);
}
}
1.15、对象
-
对象的特性就是属性
-
对象同时具有属性和方法二项特性
-
引用类的属性:对象名.属性名 = 值;
2、继承
2.1、super关键字
在子类里面,可以用过super关键字显示的调用父类的属性和方法
语法格式:super.属性名 或者 super.方法名
public void show() {
// 代码复杂度就高的多了!! 有可能是Person的, 还有可能是Person父亲的....
// hello();
// 从父类继承过来的!!
System.out.println("学的的姓名是:" + super.name);
System.out.println("学的年龄是:" + age);
System.out.println("学的学号是:" + this.num);
}
2.2、所有类的超类是Object
我们用的toString这些都是从父类继承过来的方法!!
2.3、子类覆盖父类的方法
2.4、Student类覆盖父类的show方法
/**
* 学生类
*/
public class Student extends Person {
// 学号
public int num;
// 父类的show方法不好用,我要定义自己的
// 方法覆盖,方法重写
// 所谓的方法覆盖,重写: 就是把父类的方法签名原封不动拷贝一份到子类,然后只改方法体
@Override
public void show() {
System.out.println("学生的姓名是:" + name);
System.out.println("学生的年龄是:" + age);
// num是子类特有的
// 父类是不能访问子类的东西
// 解决不了!!(父类)
System.out.println("学生的学号是:" + num);
}
@Override
public void hello() {
System.out.println("sfsdfdsfsdf");
}
}
2.5、子类构造方法里面调用父类构造方法
语法:super() 调用父类的无参构造方法
super(值); 调用父类的有参构造方法
public Car(int speed) {
// 调用父类的有参构造方法 public Vehicle(int capacity)
// 只能写在第一行。子类构造方法里面调用父类构造方法,必须写在第一行
super(4); // 代表可以载4个人
this.speed = speed;
System.out.println("执行汽车类的有参构造方法!");
}
代码实例:
/**
* 普通家用汽车类
*/
public class Car extends Vehicle{
// 默认是包访问权限
int speed; // 速度
public Car() {
super(); // 显示调用父类的无参构造方法
speed = 0;
System.out.println("执行汽车类的无参构造方法!");
}
public Car(int speed) {
super(4); // 显示调用父类的有参构造方法
this.speed = speed;
System.out.println("执行汽车类的有参构造方法!");
}
public int speedUp() { // 加速
speed += 10;
return speed;
}
public int speedDown() { // 减速
speed -= 15;
return speed;
}
public void print() {
System.out.println("Car速度是:" + speed);
System.out.println("");
}
}
2.6、向上转型【就是子类对象赋值给父类】
语法:父类 对象名 = new 子类();
public class Test1 {
public static void main(String[] args) {
// 问题1: 学生就是学生,学生对象的类型就是学生类型
Student stu = new Student();
System.out.println(stu);
// 问题2:学生是不是人? (学生是不是Person)
// Student其实还是Person
// 学生是学生的同时,还是Person
// stu2数据类型是什么???
// 没点哪个run之前它的类型就是Person
// 但是当我点了run之后,它的类型就变成Student
// 定义 -》 把子类对象赋给父类引用,这个叫向上转型
// 语法: 父类 对象名 = new 子类(); 这个就叫向上转型
// 编译类型 = 运行类型
Person stu2 = new Student();
System.out.println(stu2);
// 猜一下 - 》就近原则
// 这一句代码有多种结果!!!所以我们说这个具有多种形态!!
// 按照运行类型
stu2.show(); // show调用的Person里面的,还是Studeent里面的? 现在呢?
}
}
2.7、向下转型
-
向下转型,其实就是把继承图上面的箭头往下, 把父类往子类转。
-
把o向下转型 -> 其实就是把编译类型转换为实际的运行类型
public class Test5 {
public static void main(String[] args) {
// 向上
// Person p = new Student();
// 向下
//Studen stu = p;
// 写法1
ArrayList list1 = new ArrayList();
// 写法2 -》 向上转型
AbstractList list2 = new ArrayList();
// 写法3 -》向上转型 < - 工作中
// 面向对象编程
// 面向接口编程
List list3 = new ArrayList();
list3.add("陈永仁");
list3.add("刘建明");
list3.add(new Student());
list3.add(new Teacher());
list3.add(true);
// 需求: 遍历这个集合,只打印学生和老师???
// 说白了: 判断o的运行类型是什么....
// if(o == Student) ...
// if(o == Teacher)
for (Object o : list3) {
// 通过instanceOf 关键字来判断对象运行时的类型!!!
if (o instanceof Student) {
// 既然o已经是学生了
// 父类不能直接调子类的方法-》至少编译期间
// 把o向下转型 -> 其实就是把编译类型转换为实际的运行类型
Student stu = (Student)o;
System.out.println(stu.name);
// System.out.println(stu.stuId);
}
if (o instanceof Teacher) {
Teacher t = (Teacher) o;
System.out.println(t.name);
System.out.println(t.workId);
}
}
}
}
2.8、再提访问修饰符
2.9、final类
2.10、abstract关键字
可以修饰类,就变成抽象类
可以修饰方法,就变成抽象方法了
2.11、abstract类、abstract方法
2.12、interface接口
2.12.1、定义接口使用interface关键字,里面的方法都是抽象方法。
2.12.2、接口的实例必须通过实现类来完成
2.12.3、接口的语法格式
class 实现类 implements 接口 {
}
接口 对象名 = new 实现类
package com.woniu.t4;
// 很多学Java - > 自学 -》 基本就到了面向对象就过不去了
// 思考:为什么要学继承,解决了那些问题,不用继承优缺点
/**
* 这个就是一个接口
* 接口里面只能是抽象方法!!!!(JDK1.8之前)
* 吧class改成inerface
*/
public interface Father {
// 接口里面可以定属性嘛? 可以 - , 但是你要小心!!
// 接口里面的属性只能是public && static && final (静态常量)
// 实际可以省略,默认就是
int MONTH = 12;
// 接口里面的方法默认就是抽象的,并且【public】的
// 所以在接口里面的抽象方法,可以省略【abstract】关键字,以及访问修饰符
public abstract void show();
void hello();
}
// implements 英文的意思就是实现!!
// Child读:Child类是Father接口的实现
class Child implements Father {
@Override
public void show() {
System.out.println("child show..");
}
@Override
public void hello() {
System.out.println("child hello..");
}
}
测试类:
package com.woniu.t4;
public class Test {
public static void main(String[] args) {
// 创建接口的实例 - > 不能直接实例
// 语法:接口 对象名 = new 实现类();
Father f = new Child();
f.show();
f.hello();
}
}