1
package javaSE;
/*
1.final是java语言中的一个关键字
2.final表示最终的,不可变的
3.final可以修饰变量,方法,类
4.final修饰的变量?
一旦被创建并赋值无法被修改
--只能赋一次值
5.final修饰的方法?
无法被覆盖,被重写
6.final修饰的类?
final修饰的类无法被继承
7.调用子类特有的方法需要向下转型
8.final管的不是能不能调用,而是能不能改
就是说你创建对象去调用,没问题
但你继承时进行修改就有问题了
*/
public class p327final修饰的类无法继承 {
public static void main(String[] args){
//局部变量
int i=100;
//重新赋值
i=200;
//局部变量
final int k=100;
//k=300;
}
}
class A{
public final void dosome(){
System.out.println("aaaaaaa");
}
}
//B继承A相当于对A类的功能的扩展
//你可以给A类加上final,使得A类不能被继承
class B extends A{
/*
public void dosome(){
System.out.println("bbbbbbbbb");
}
*/
}
======================================================================================================================================================================================================================================================================================================================================================
2
package javaSE;
/*
final修饰的变量,如果这个变量是一个"引用"会怎么样???
<<重点>>final修饰的变量只能赋一次值
"引用"是不是一个变量?
是
final修饰的"引用"始终指向第一次赋值的对象,无法进行改变,使得该对象
无法被垃圾回收器回收
"引用"保存的是对象的内存地址,修改对象的属性,不影响内存地址(即没有对"引用"进行修改)
*/
public class p330final修饰引用 {
public static void main(String[] args){
//创建对象,引用保存
final a s=new a(30);
//重新赋值
//s=new a(40); 不被允许
s.age=10;
System.out.println(s.age);//可以
//这并不是对s保存的数据进行一个改变,s保存的是对象的储存地址
//这是没变的,只是将对象的属性改变了
}
}
class a{
int age;
public a(int i){
age=i;
}
}
======================================================================================================================================================================================================================================================================================================================================================
3
package javaSE;
/*
final修饰实例变量呢?
<<重点>>final修饰的变量只能赋值一次
你是否还记得:实例变量没有手动赋值,系统会默认赋值
结论:
final修饰的实例变量,系统不管赋默认值,必须程序员手动赋值
实例变量在什么时候赋值(初始化)?
构造方法执行的时候赋值(如果你不给,系统会赋默认值)
*/
public class p331final修饰实例变量{
public static void main(String[] args){
}
}
class ah{
//实例变量
final int age;
public ah(){
this.age=10;
}
}
======================================================================================================================================================================================================================================================================================================================================================
4
package javaSE;
/*
final修饰的实例变量一般添加static修饰
因为final修饰的变量是无法被更改的相当于常量
没必要每创建一个对象,都开辟空间来储存他(这样相当于创建10个对象,为这个常量开辟了10个空间)
static final 数据类型 变量名(将变量变为静态的储存在方法区)
static final联合修饰的变量成为"常量"
常量:实际上常量和静态变量一样,区别在于:
常量的值不能变
常量和静态变量,都是储存在方法区,并且在类加载时初始化
*/
public class P332常量 {
}
======================================================================================================================================================================================================================================================================================================================================================
5
package javaSE;
/*
类到对象时实例化,对象到类时抽象
抽象类:
1.什么是抽象类?
类和类之间具有共同特征,将这些共同特征提取出来,形成的就是抽象类
类本身是不存在的,所以抽象类无法创建对象<<无法实例化>>
2.抽象类属于什么数据类型?
抽象类也属于引用数据类型
3.抽象类怎么定义?
语法:
[修饰符列表] abstract class 类名{
类体
}
4.抽象类是无法实例化的,无法创建对象,所以抽象类是用来被子类继承的
5.final和abstract不能联合使用,因为抽象类就是要被子类继承的
final abstract
6.抽象类的子类还可以是抽象类
abstract class aa extends cc{
}
7.抽象类虽然无法实例化,但抽象类有构造方法,这个构造方法是供子类使用的
8.抽象类关联到一个概念:抽象方法,什么是抽象方法?
抽象方法表示没有实现的方法,没有方法体的方法.例如
public abstract void dosome();
抽象方法特点:
1.没有方法体,以;结尾
2.前面修饰符列表中有abstract关键字
9.抽象类可以有抽象方法和非抽象方法,但抽象方法只能存在抽象类
*/
public class p334抽象类{
public static void main(String[] args){
}
}
abstract class aa{
public aa(int a){
}
}
/*
这里会去调用''aa''中的无参数构造方法
但是''aa''中没有无参数的构造方法(因为你写了一个有参数的构造方法,系统不会默认给无参数的构造方法)
所以下面代码会报错
abstract class bb extends aa{
public bb(int a){
super();
}
}
*/
======================================================================================================================================================================================================================================================================================================================================================
6
package javaSE;
/*
抽象类可以有抽象方法,非抽象方法 抽象方法只能存在于抽象类中
子类(非抽象类)想要继承父类(抽象类),需要将父类中的抽象方法''实现''
<<感觉像是,你必须给他"移动"(做某件事情的能力)>>
面向抽象编程:
动物 s=new 鸟();//像上转型
s.move();<<编译会方法''动物''中的move,运行会访问''鸟''中的move
降低程序的耦合度,提供程序的扩展力
符合ocp原则
面试题(判断题):java语言中凡是没有方法体的方法都是抽象方法
不对,Object类中就有很多方法都没有方法体,都是以;结尾的,但他们都不是
抽象方法,例如:
public native int hashCode();
这个方法底层调用了c++写的动态链接库程序
有一个native表示调用JVM本地程序
*/
public class p338非抽象类继承抽象类必须将抽象方法实现{
public static void main(String[] args){
//这里可以使用多态
//父类型引用指向子类型对象
动物 s=new 鸟();//面向抽象编程
//这里用的是,鸟类当中的方法
s.move();
}
}
abstract class 动物{
public abstract void move();//这是一个抽象类
}
/*
//子类,非抽象的
class 鸟 extends 动物{
''这里会报错,原因在于,鸟会继承动物的move()方法这是一个抽象方法
而抽象方法只能在抽象类中
}
*/
//子类,非抽象的
class 鸟 extends 动物{
public void move(){
System.out.println("aaaa");
}
}
======================================================================================================================================================================================================================================================================================================================================================
7
package javaSE;
/*
接口:
1.接口也是一种"引用数据类型",编译后也是一个class字节码文件
2.接口是完全抽象的(抽象类是半抽象的)或者说接口是特殊的抽象类
3.接口怎么定义? 语法是什么?
--接口:[修饰符列表] interface 接口名{
}
--类:[修饰符列表] class 类名{
类体
}
--抽象类:[修饰符列表] abstract class 类名{
类体
}
4.接口支持多继承
5.接口中只包含两部分内容,一部分是:"常量" 一部分是:"抽象方法".接口中不包含除此之外的其他内容
6.接口中所有元素都是public修饰的(都是公开的)
7.接口中的抽象方法定义时:public abstract修饰符可以省略
8.接口中的方法都是抽象方法,所以接口中不能有方法体
9.接口中常量的public static final 数据类型 变量名=数据;
可以写成数据类型 变量名=数据;
*/
public class P340接口的基础语法{
public static void main(String[] args){
}
}
//定义接口
interface x{
}
//接口的继承
interface f extends x{
}
//接口支持多继承
interface r extends f,x{
}
interface k{
//抽象方法
//public abstract int Mymath(int a,int b);
//接口中都是抽象方法,那么在编写代码时public abstract可以省略吗?
int Mymath(int a,int b);
}
======================================================================================================================================================================================================================================================================================================================================================
8
package javaSE;
/*
接口的基础语法:
1.类和类之间叫继承,类和接口之间叫做实现
别多想:你仍然可以将"实现"看作"继承"(把抽象的东西,变得相对具体)
继承用:extends
实现用implements
五颗星(*****):
当一个非抽象的类实现接口的话,必须将接口中所有的抽象方法全部实现(覆盖/重写)
重写的方法权限修饰符要大于等于"以前"
interface ds{
double k=100;
int sum(int a,int b);<<这是一个public的抽象方法>>
}
所以:
重写也为public
public int sum(int a,int b){
return a+b;
}
如果你这样写会报错
int sum(int a,int b){
return a+b;
}
*/
public class p345类实现接口要实现所有方法{
public static void main(String[] args){
}
}
interface ds{
double k=100;
int sum(int a,int b);
int sub(int a,int b);
}
class adw implements ds{
//非抽象类实现(继承)接口需要将所有的抽象方法实现
public int sum(int a,int b){
return a+b;
}
public int sub(int a,int b){
return a-b;
}
/*
如果你这样写会报错
int sum(int a,int b){
return a+b;
}
*/
}
======================================================================================================================================================================================================================================================================================================================================================
9
package javaSE;
public class p347接口和多态联合使用{
public static void main(String[] args){
//多态
dda bian=new das();
System.out.println(bian.sum(20,10));
System.out.println(bian.sub(20,10));
}
}
interface dda{
int sum(int a,int b);
int sub(int a,int b);
}
class das implements dda{
public int sum(int a,int b){
return a+b;
}
public int sub(int a,int b){
return a-b;
}
}
======================================================================================================================================================================================================================================================================================================================================================
10
package javaSE;
/*
接口中的方法时这么定义的,那么实现时返回值只能是"void"
interface dsad{
void yi();
}
重点(*****):一个类可以同时实现多个接口
这种机制弥补了Java中的那个缺陷?
java中类和类之间只支持单继承.实际上单继承是为了简单而出现的,现实世界中存在多继承
java中的接口弥补了单继承带来的缺陷
接口和接口之间在进行强转类型转换时,没有继承关系,也可以强转
但一定要注意运行时可能出现异常
养成好习惯,强转向下转型时进行判断
if(m instanceof n){ n是k的实例
}
*/
public class p348一个类可以实现多个接口{
public static void main(String[] args){
dsad bianliang1=new lei();
dsa bianliang2=new lei();
//dsad和dsa之间没有继承关系但可以强转类型转换
//编译不报错,运行不报错
dsa bianliang3=(dsa)bianliang1;
bianliang3.er();
//这里当然也可以直接向下类型转换
lei a=(lei)bianliang1;
a.er();
//这两个接口之间没有任何关系,强转类型转换 编译不报错,但运行会报错
dws i=(dws)bianliang1;