抽象类的概述
抽象类
针对一个事物,如果这个事物并不是具体事物,而是概括性的(需要抽象修饰这个类),比如动物,应该定义不应该定义具体类class Animal{},并且动物的eat()/sleep()每个具体动物吃和睡不同的,所以这些功能应该声明(方法不能有方法主体)将当前这个类定义为抽象类!
格式:
abstract class Animal{} 动物是一个抽象类
抽象方法
只是给定义一个方法声明,没有方法主体({})
权限修饰符 返回值类型 方法名();
比如:动物的吃的功能 (抽象的,因为每一个动物吃的是不一样的,定义父类该功能必须为一个抽象)
public abstract void eat() ;
抽象类的特点
抽象类是特点
抽象类不能实例化!(不能创建对象)
父类强制子类完成重写抽象方法!
抽象类成员特点:
成员变量
既可以是变量也可以是常量
成员方法:
既可以是抽象的(子类必须重写),也可以是非抽象的
构造方法:
抽象类中是可以存在构造方法(无参/有参),作用:对该类对象的数据进行构造初始化
抽象类的应用
假如我们在开发一个系统时需要对员工类进行设计,包含程序员以及经理,程序员和经理的工作性质不同! 行为:work() ;
程序员包含3个属性:姓名(name)、工号(empID)以及工资(salary)。
经理也是员工,除了含有员工的属性外,另为还有一个奖金属性(bouns)。
abstract class YuanGong{
public YuanGong(){
}
private String name;
private String empID;
private int salary;
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setEmpID(String empID){
this.empID=empID;
}
public String getEmpID(){
return empID;
}
public void setSalary(int salary){
this.salary=salary;
}
public int getSalary(){
return salary;
}
public abstract void work();
}
class CengXuYuan extends YuanGong{
public CengXuYuan(){
}
public void work(){
System.out.println("我需要敲代码");
}
}
class JingLi extends YuanGong{
public JingLi(){
}
private int bouns;
public void setBouns(int bouns){
this.bouns=bouns;
}
public int getBouns(){
return bouns;
}
public void work(){
System.out.println("我需要谈项目");
}
}
class CeChou{
public static void main(String[] args){
YuanGong y=new CengXuYuan();
y.setName("李炳谦");
y.setEmpID("Y15775652");
y.setSalary(8000);
System.out.println(y.getName()+"---"+y.getEmpID()+"---"+y.getSalary());
y.work();
System.out.println("-----------------------------------------");
YuanGong g=new JingLi();
g.setName("董言龙");
g.setEmpID("J15455652");
g.setSalary(22100);
JingLi j=(JingLi)g;
j.setBouns(6000);
System.out.println(g.getName()+"---"+g.getEmpID()+"---"+g.getSalary()+"---"+j.getBouns());
g.work();
}
}
接口
接口:就是体现的一种的扩展性(现实世界事物额外的行为)
接口定义的格式:
interface 接口名{}
定义接口名和定义类名的规则是一样的,单个单词第一个字母大写
多个单词 每个单词首字母大写
接口中的方法是抽象方法;
实际开发中,定义接口
interface 接口名{}
子实现类的命名
class 类名+Impl implements 接口名{}
接口中的成员特点
接口中的成员特点
成员变量:
存在默认的修饰符 public static final ,接口变量只能是常量!
被静态修饰的成员变量: 可以被类名或者是接口名访问
构造方法:
没有构造方法
成员方法:
接口的方法是抽象方法,存在默认修饰符 public abstract (以后jdk8新特性)
类与类,类与接口以及接口与接口的关系
类与类的关系:
extends 继承关系, 只支持单继承,不支持多继承,但是多层继承!
类与接口的关系:
implements 实现关系 并且一个类继承自另一个类的同时,可以实现多个接口 (Java底层源码中很多都是)
Java中的任意类(自定义的类,官方提供的api的类)继承自Object
接口与接口的关系:
extends 继承关系: 可以单继承,也可以多继承! (多继承技术仅限于Java中接口)
抽象类和接口的区别
1)成员的区别
抽象类
成员变量:
既可以是常量,也可以是变量 !
构造方法:有,无参构造/有参构造方法 ,作用:通过具体的子类进行实例化!(对对象的数据初始化)
成员方法:
既可以是抽象的,也可以是非抽象的,
如果抽象的成员方法,必须携带public abstract 声明
接口
成员变量:
只能是常量: 存在默认的修饰符 :public static final
构造方法:不存在
成员方法: 存在默认修饰符
public abstract 可以省略不写! (建议刚开始写接口中的方法,带上修饰符)
2)关系的区别
类与类的关系: (类可以是抽象类)
extends 继承关系, 只支持单继承,不支持多继承,但是多层继承!
类与接口的关系:
implements 实现关系 并且一个类继承自另一个类的同时,可以实现多个接口 (Java底层源码中很多都是)
Java中的任意类(自定义的类,官方提供的api的类)继承自Object
接口与接口的关系:
extends 继承关系: 可以单继承,也可以多继承! (多继承技术仅限于Java中接口)
3)设计理念的区别
抽象类多态进行对象的创建, 体现的也是一种"is a"的关系
接口的实例化,需要通过子实现类实例化, (implements),体现的是一种"like a" 的关系
跳高狗/计算猫 —>都是通过学习了额外的动作实现的;
应用 猫狗案例
interface AnimalTrain{
public abstract void jump();
}
abstract class Animal{
public Animal(){
}
private String name;
private int age;
private String color;
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
public void setColor(String color){
this.color=color;
}
public String getColor(){
return color;
}
public abstract void eat();
public abstract void sleep();
}
class Cat extends Animal {
public Cat(){
}
public void eat(){
System.out.println("我吃鱼");
}
public void sleep(){
System.out.println("我睡沙发");
}
}
class Dog extends Animal {
public Dog(){
}
public void eat(){
System.out.println("我吃骨头");
}
public void sleep(){
System.out.println("我睡狗窝");
}
}
class JumpCat extends Cat implements AnimalTrain{
public JumpCat(){
}
public void jump(){
System.out.println("我这个猫会跳高");
}
}
class JumpDog extends Dog implements AnimalTrain{
public JumpDog(){
}
public void jump(){
System.out.println("我这个狗会跳高");
}
}
class JiCe{
public static void main(String[] args){
Cat c=new JumpCat();
c.setName("Tom");
c.setAge(2);
c.setColor("蓝色");
System.out.println(c.getName()+"---"+c.getAge()+"---"+c.getColor());
c.eat();
c.sleep();
AnimalTrain cj=new JumpCat();
cj.jump();
System.out.println("--------------------------------------------------");
Dog d=new JumpDog();
d.setName("Jack");
d.setAge(2);
d.setColor("白色");
System.out.println(d.getName()+"---"+d.getAge()+"---"+d.getColor());
d.eat();
d.sleep();
AnimalTrain dj=new JumpDog();
dj.jump();
}
}
数组之选择排序
选择排序
使用0索引对应的元素一次和后面索引对应的元素进行比较,第一次比较完毕
最小值就出现最小索引处
然后使用1…依次比较
规律:
使用0索引对应的元素和后面的索引对应的元素比较
使用1索引…
…
使用arr.length-2索引的对应的元素和arr.length-1索引的对应的元素比较
将冒泡排序和选择排序区分开来!
class ArrayTest{
public static void main(String[] args){
//自定义一个数组,静态初始化
int[] arr = {24,69,57,87,13} ;
System.out.println("排序前:") ;
//遍历数组
printArray(arr) ;
//排序
/*
//第一次比较
//定义初始化索引
int x = 0 ;
for(int y = x +1 ; y < arr.length; y++){
//判断:如果当前arr[y]都小于arr[x] ,互换 :将小的往前放
if(arr[y] < arr[x]){
//定义中间变量互换
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
System.out.println("第一次排序后:") ;
//遍历
printArray(arr) ;
System.out.println("--------------") ;
//第二次比较
x = 1 ;
for(int y = x + 1 ; y < arr.length ; y ++){
//判断
if(arr[y] < arr[x]){
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
System.out.println("第二次排序后:") ;
//遍历
printArray(arr) ;
System.out.println("--------------") ;
//第三次比较
x = 2 ;
for(int y = x + 1 ; y < arr.length ; y ++){
//判断
if(arr[y] < arr[x]){
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
System.out.println("第三次排序后:") ;
//遍历
printArray(arr) ;
System.out.println("--------------") ;
//第四次比较 //x = 0,1,2,3
x = 3 ;
for(int y = x + 1 ; y < arr.length ; y ++){
//判断
if(arr[y] < arr[x]){
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
System.out.println("第四次排序后:") ;
//遍历
printArray(arr) ;
*/
//代码重复读高,使用循环改进:
//x = 0,1,2,3
for(int x = 0 ; x < arr.length-1 ; x ++){
for(int y = x +1 ; y < arr.length ; y++){
if(arr[y] < arr[x]) {
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
}
System.out.println("排序后:") ;
printArray(arr) ;
System.out.println("-------------------------") ;
//使用方法改进:将选择排序定义到方法中
System.out.println("排序后:") ;
selectSort(arr) ;
//遍历数组:输出排序的结果
printArray(arr) ;
}
public static void selectSort(int[] arr){
for(int x = 0 ; x < arr.length-1 ; x ++){
for(int y = x +1 ; y < arr.length ; y++){
if(arr[y] < arr[x]) {
int temp = arr[x] ;
arr[x] = arr[y] ;
arr[y] = temp ;
}
}
}
}
public static void printArray(int[] arr){
System.out.print("[") ;
for(int x = 0 ; x < arr.length ; x ++){
if(x==arr.length-1){
System.out.println(arr[x]+"]") ;
}else{
System.out.print(arr[x]+", ") ;
}
}
}
}