访问控制修饰符
public
允许跨工程访问的类
protected
允许同包类+子类访问
default
(不写修饰符默认隐藏)同包类
private
只允许本类访问
权限大小比较
public > protected > default > private
this和super关键字
this
this代表本类对象的一个引用对象。
--构造函数中,this()必须放在第一行。
--当局部变量和成员变量同名时,用于区分。
--构造方法之间互相调用
public class Test_This {
public static void main(String[] args) {
new Demo().test();//通过对象,来访问类里的成员(成员变量和成员方法)
}
}
class Demo{
int count = 20 ;//成员变量
public void test() {
int count = 10;//局部变量
System.out.println(count);//10,变量的就近原则,会使用局部变量 的值
//想要使用 和 局部变量 同名的 成员变量count--this调用成员变量
//this表示的是本类的对象的引用--底层帮你new了一个本类对象--Demo this = new Demo();
System.out.println( this.count );//20,成员变量
}
}
public class Test_This2 {
public static void main(String[] args) {
new Demo2(1);
//输出:
//无参构造
//含参构造1
}
}
class Demo2{
public Demo2() {
System.out.println("无参构造");
}
public Demo2(int a) {
this();//在构造方法中,使用this关键字,必须是第一条语句
System.out.println("含参构造"+a);
}
}
super
super代表父类对象的一个引用对象
--通过super关键字可以使用父类的内容
--如果用super,必须出现在调用位置的第一行
public class Test_Super {
public static void main(String[] args) {
new Zi3(); //父类无参构造
//子类无参构造
new Zi3("含参"); //父类无参构造
//子类含参构造
}
}
class Fu3{
//如果父类有含参构造,子类找不到无参构造,需要在子类中使用super去调用父类的含参构造
public Fu3(String name) {
System.out.println("父类含参构造");
}
}
class Zi3 extends Fu3{
public Zi3() {
//super();如果没有super,在此处隐藏了--子类的构造方法中都会隐藏着父类的无参构造
super("含参");
System.out.println("子类无参构造");
}
public Zi3(String name) {
//此处也隐藏了super();证明子类每一个构造都隐藏了父类无参构造
super("含参");
System.out.println("子类含参构造");
}
}
this和super比较
1、 this代表本类对象的引用,super代表父类对象的引用。
2、 this用于区分局部变量和成员变量
3、 super用于区分本类变量和父类变量
4、 -- this.成员变量 --- this.成员方法() --- this(参数)代表调用本类内容
5、 --super.成员变量--super.成员方法()--super(参数)代表调用父类内容
6、 this和super不可以同时出现在同一个构造方法里,他们两个只要出现都得放在第一行,同时出现的话,到底第一行放谁呢。。
static和final关键字
static
static用于修饰成员(变量&方法),使其成为静态资源。
特点
1、 可以修饰成员变量,成员方法
2、 随着类的加载而加载,优先于对象加载
3、 只加载一次,就会一直存在,不再开辟新空间
4、 全局唯一,全局共享
5、 可以直接被类名调用
6、 静态只能调用静态,非静态可以随意调用
7、 static不能和this或者super共用,因为有static时可能还没有对象
public class Test_Static {
public static void main(String[] args) {
//2,静态资源优先于对象加载,因为是随着类的加载就已经加载了
Student.coding();//null
//正在敲代码
System.out.println(Student.name);//null
Student s = new Student();
s.study();//10
//null
//null
//正在敲代码
//正在学习java
System.out.println(s.age);//10
//1,静态资源,多了一种访问方式,除了可以用对象访问,更提倡用类名直接调用
Student.coding();//null
//正在敲代码
System.out.println(Student.name);//null
//3,静态资源是共享资源,能够被多个对象共享
Student s1 = new Student();
s1.name="张三";
Student s2 = new Student();
System.out.println(s2.name);//张三
}
}
class Student{
//普通资源
int age = 10;
public void study() {
//6,非静态调用关系? -- 调用任意资源
System.out.println(age);
System.out.println(name);
coding();
System.out.println("正在学习java");
}
//静态资源
static String name ;
static public void coding() {
//4,静态资源里,不能使用this或者super关键字!
//this.study();
//super.
//5,静态调用关系? -- 只能调用静态,不能调用非静态的
System.out.println(name);
System.out.println("正在敲代码");
}
}
final
final表示最终,可以修饰类、成员变量、成员方法。
特点
1、 被final修饰的类,不能被继承
2、 被final修饰的方法,不能被重写
3、 被final修饰的变量是个常量,值不能被更改
4、 常量的定义形式: final 数据类型 常量名 = 值
public class Test_Final {
public static void main(String[] args) {
Zi d = new Zi();
d.speak();//Fu..speak()
System.out.println(d.name);//欢欢
d.test();//欢欢
}
}
class Fu{
//final class Fu{
//1,被final修饰的类,不能被继承
final String name="欢欢";
public final void speak(){
System.out.println("Fu..speak()");
}
}
class Zi extends Fu{
//public void speak(){ }
//2,被final修饰的方法,不能被重写
public void test(){
//super.name="大黄";
//3,被final的变量,不能重新被赋值
System.out.println(super.name);
}
}
异常
用来封装错误信息的对象(bug)。
组成结构:类型,提示,行号。
Throwable
Throwable - 顶级父类
-Error:系统错误,无法修复
-Exception:可修复的错误
-RunTimeException
-ClassCastException
-ClassNotFoundException
Exception
程序中遇到了异常(Exception),通常有两种处理方式:捕获或者向上抛出。
当调用了一个抛出异常的方法时,调用位置可以不做处理继续向上抛出也可以捕获异常。
1.捕获异常(使用try{}catch{})
try{
需要捕获的代码
}catch(异常类型 异常名){
处理方案
}
测试
import java.util.InputMismatchException;
import java.util.Scanner;
//测试 异常
public class Test_Exception {
public static void main(String[] args){
method();//捕获异常
}
/* 捕获异常
* try{ 代码... }catch(异常类型 异常名){ 合理的解决方案 }
* 异常类型: ArithmeticException / InputMismatchException
*/
public static void method() {
try {
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a/b);
}catch(InputMismatchException a) {
System.out.println("请输入两次整数!");
}catch(ArithmeticException a) {
System.out.println("第二次输入的整数不能为0 !");
}catch(Exception a) {
//怎么捕获其他的所有异常呢?--多态--通用性强-不关心子类类型,把子类当做父类来看
//所有Exception的子类都能被捕获!
System.out.println("请输入正确的数据!!");
}
}
}
多组数据结果
0
0.1
请输入两次整数!
5
0
第二次输入的整数不能为0 !
2.抛出异常(方法上使用throws 异常类型)
main() throws InputMismatchException{}
测试
import java.util.Scanner;
public class Test_Exception2 {
public static void main(String[] args){
try {
//调用了抛出异常的method2(),需要处理,捕获或者抛出二选一
method2();//抛出异常
}catch(Exception e) {
System.out.println("运算错误!");
}
}
/* 抛出异常
* 在方法声明上加 throws 异常类型1,异常类型2...
*/
public static void method2() throws Exception{
int a = new Scanner(System.in).nextInt();
int b = new Scanner(System.in).nextInt();
System.out.println(a/b);
}
}
5
0
运算错误!
代码块
被 { } 包起来的一段代码就叫代码块
构造代码块
特点
1、 在类的内部,方法外部,的代码块。
2、 通常用于抽取构造方法中的共性代码。
3、 每次调用构造方法前都会调用构造代码块
4、 优先于构造方法加载
局部代码块
特点
1、 在方法里面的代码块
2、 通常用于控制变量的作用范围,出了括号就失效
3、 变量的范围越小越好,成员变量会有线程安全问题
静态代码块
随着类的加载而加载,并且只被加载一次,一般用于项目的初始化
static{…}//在成员位置,拥有static关键字的代码块
特点
1、 静态代码块:static{ },位置:在类里方法外
2、 在类加载时就执行,不管创建多少对象,只会执行一次的代码块
执行顺序(代码块+构造方法+继承)
总体顺序:
启动程序 -> 父类静态代码块 -> 子类静态代码块 -> 子类main方法 -> new SubClass( ) -> 父类构造代码块 -> 父类构造方法中局部代码块 -> 子类构造代码块 -> 子类构造方法中局部代码块
class Parent {
public static String p_StaticField = "父类-静态变量";
public String p_Field = "父类-变量";
protected int i = 1;
protected int j = 2;
static {
System.out.println( p_StaticField ); // 1.
System.out.println( "父类-静态代码块" ); //2.
}
{
System.out.println( p_Field ); // 7.
System.out.println( "父类-构造代码块" ); // 8.
}
public Parent()
{
System.out.println( "父类-局部代码块" ); // 9.
System.out.println( "i=" + i + ", j=" + j ); // 10.
j = 3;
}
}
public class SubClass extends Parent {
public static String s_StaticField = "子类-静态变量";
public String s_Field = "子类-变量";
static {
System.out.println( s_StaticField ); // 3.
System.out.println( "子类-静态代码块" ); // 4.
}
{
System.out.println( s_Field ); // 11.
System.out.println( "子类-构造代码块" ); // 12.
}
public SubClass()
{
System.out.println( "子类-局部代码块" ); // 13.
System.out.println( "i=" + i + ",j=" + j ); //14.
}
public static void main( String[] args )
{
System.out.println( "main方法开始" ); // 5.
new SubClass(); // 6.
}
}
执行结果:
父类-静态变量
父类-静态代码块
子类-静态变量
子类-静态代码块
main方法开始
父类-变量
父类-构造代码块
父类-局部代码块
i=1, j=2
子类-变量
子类-构造代码块
子类-局部代码块
i=1,j=3
抽象类和接口
抽象类
概念
Java中可以定义没有方法体的方法,该方法由其子类来具体的实现。该没有方法体的方法我们称之为抽象方法,含有抽象方法的类我们称之为抽象类。
特点
1、 通过java关键字abstract实现
2、 可以修饰方法或者类
3、 抽象类中可以没有抽象方法(由子类去实现)
4、 如果类中有抽象方法,那该类必须定义为一个抽象类
5、 子类继承了抽象类以后,要么还是一个抽象类,要么就把所有抽象方法都重写
6、 多用于多态中
7、 抽象类不可以被实例化
import java.io.IOException;
import java.io.Reader;
//测试 抽象类
public class Test_Abstract {
public static void main(String[] args) {
//创建多态对象--父类引用 指向 子类对象
//Animal2 a = new Dog2();//8,抽象类不能被实例化
Animal2 a = new Cat2();
a.eat();//父类的方法声明,父类的方法体
a.sleep();//父类的方法声明,子类的方法体(重写了)
}
}
//1,为什么产生父类?--为了提取子类的共性,提高父类代码的复用性
//2,怎么优化父类?--程序设计--父类有没有可以省略的功能--方法体可以省略
//4,如果类里包含抽象方法,那么,这个类就是一个抽象类
//5,使用abstract关键字描述抽象
abstract class Animal2{
public void eat() {
System.out.println("Animal...eat()");
}
//3,如果有方法体,写了也要被修改,那就可以省略不提供--没有方法体的方法--抽象方法
abstract public void sleep() ;
}
//6,子类继承抽象类后,就继承来了抽象方法,是一个 抽象的 子类
abstract class Dog2 extends Animal2 {
}
//7,子类继承抽象类后,子类可以重写 所有的 抽象方法
class Cat2 extends Animal2 {
@Override//注解,作用是用来标志这个方法是一个重写方法
public void sleep() {
System.out.println("猫吃鱼");
}
}
class SubReader extends Reader{
//抽象方法必须重写,否则就是一个抽象类
//普通方法不是必须重写,而是要改才重写
public void close() throws IOException{
System.out.println("close() ");
}
public int read(char cbuf[], int off, int len) throws IOException{
System.out.println("read() ");
return 0 ;
}
}
构造方法
1、 抽象类里有构造方法
2、 抽象类自己不能被实例化,仍然会提供构造方法,用于帮助子类初始化
3、 当创建子类对象时,会触发子类的构造方法,子类的构造方法里第一条默认就会有super()
4、 构造方法的执行顺序: 父类的 --> 子类的
public class Test_Abstract2 {
public static void main(String[] args) {
//2,先执行父类的 构造方法 ,再执行自己的构造方法
Animal3 a = new Dog3();
}
}
//创建抽象类
abstract class Animal3{
//3,抽象类不能被实例化,为什么还要提供构造方法?--为了方便子类new
public Animal3() {
System.out.println("Animal3..无参构造");
}
}
class Dog3 extends Animal3{
public Dog3() {
super();//1,默认就存在,会主动找父类的无参构造
System.out.println("Dog3..无参构造");
}
}
成员变量和成员方法
1、 既可以有变量,也可以有常量。
2、 抽象类里,既可以有普通方法,有可以有抽象方法。
3、 抽象类里可以都是普通方法,目的是不让外界实例化
测试成员变量
public class Test_Abstract3 {
public static void main(String[] args) {
System.out.println( new Demo2().age );//10
//new Demo2().name = "123" ;final的常量,值不能被修改
System.out.println( new Demo2().name );//Demo
}
}
abstract class Demo{
int age = 10 ;
final String name = "Demo";
}
class Demo2 extends Demo{
}
测试成员方法
public class Test_Abstract4 {
public static void main(String[] args) {
Demo3 d = new Demo5();//Demo3 Demo4都是抽象类不能new
d.save();//多态的目的是统一标准,一切向父类看齐
d.delete(10);
d.update("jack");
}
}
//1,抽象类是一个特殊的类,特殊在 类里可以有普通方法和 抽象方法,怎么决定类里的方法到底设计成普通方法还是抽象方法呢?--看方法体有没有必要提供
abstract class Demo3{
public void save() {
System.out.println("数据保存成功!");
}
abstract public void delete(int id) ;
abstract public void update(String name) ;
}
//2,子类继承了抽象类,只重写了一部分抽象方法,也就是还包含着抽象方法,所以仍然是一个抽象类
abstract class Demo4 extends Demo3{
public void delete(int id) {
System.out.println("delete().."+id);
}
}
class Demo5 extends Demo4{
public void update(String name) {
System.out.println("update().."+name);
}
}
接口
Java里面由于不允许多重继承,所以如果要实现多个类的功能,需要可以通过实现多个接口来实现。
Java接口和Java抽象类代表的就是抽象类型,就是我们需要提出的抽象层的具体表现。OOP[面向对象]的编程,如果要提高程序的复用率,增加程序的可维护性,可扩展性,就必须是面向接口的编程,面向抽象的编程,正确地使用接口、抽象类这些太有用的抽象类型做为java结构层次上的顶层。
特点
1、 接口中都是抽象方法
2、 通过interface关键字创建接口
3、 通过implements让子类来实现
4、 可以理解成,接口是一个特殊的抽象类
5、 接口突破了java的单继承的局限性
6、 接口和类之间可以多实现,接口和接口之间可以多继承
7、 接口是对外暴露的规则,是一套开发规范
8、 接口提高了程序的功能扩展,降低了耦合性
public class Test_Interface {
public static void main(String[] args) {
//6,接口和抽象类一样,都不可以被实例化
Demo d = new DemoImpl();
//7,多态对象为了统一调用标准,以父类为准
d.save();
d.delete();
}
}
//1,通过interface关键字,定义接口
interface Demo{
//2,接口里全都是抽象方法(jdk1.8后可以是default/static的普通方法)
abstract public void save() ;
abstract public void delete() ;
}
//3,实现类想要使用接口的功能,需要和接口发生实现关系(类似继承)
//5,实现类实现了接口,可以重写 所有 抽象方法
class DemoImpl implements Demo{
@Override//注解
public void save() {
System.out.println("数据保存成功!");
}
@Override//注解
public void delete() {
System.out.println("数据删除成功!");
}
}
//4,实现类实现了接口,可以是一个抽象的实现类
//abstract class DemoImpl implements Demo{}
接口的使用
构造方法
接口里是没有构造方法的。在创建实现类的对象时默认的super(),是调用的默认Object的无参构造。
成员变量
接口里没有成员变量,都是常量。所以,你定义一个变量没有写修饰符时,默认会加上public static final
成员方法
接口里的方法--都是抽象方法(java1.8前);
可以有static或者default的普通方法(java1.8后)
public class Test_Interface2 {
public static void main(String[] args) {
//3,使用接口里的静态常量?
//Inter.age = 30 ;//是final的常量
System.out.println( Inter.age );//20,是static的资源
System.out.println( new InterImpl().age );//20
Inter in = new InterImpl();
in.show();//这是jdk1.8的新特性
in.save();//数据保存成功!
Inter.test();//这是jdk1.8的新特性--通过类名直接访问接口里的普通的静态方法
}
}
interface Inter{
//1,接口里有没有构造方法?--没有--实现类到底怎么new的?--
//2,接口里有没有变量?--没有!!是static的final的常量public的
//public static final int age = 20 ;//接口会为你的变量,自动拼接public static final
int age = 20 ;//简写形式
//4,接口里有没有普通方法?--有,只不过是jdk1.8才提供的,必须修饰成default/static
default public void show() {
System.out.println("这是jdk1.8的新特性");
}
static public void test() {
System.out.println("这是jdk1.8的新特性");
}
//5,接口里有没有抽象方法?--有
//abstract public void save() ;//接口会为你的抽象方法,自动拼接public abstract
void save() ;//简写形式
}
//6,实现类实现接口后,对于普通方法必须重写吗?--不是,要改才重写
//7,实现类实现接口后,对于抽象方法必须重写吗?--是,否则就是一个抽象的实现类
class InterImpl extends Object implements Inter{
public InterImpl() {
//不是接口里的构造方法,因为接口根本没有构造方法,其实找的是Object的构造方法
super();
}
@Override
public void save() {
System.out.println("数据保存成功!");
}
}
接口复杂用法
1、 接口之间可以多继承,多个接口之间逗号隔开(打破了java单继承的局限性,)
2、 接口还可以多实现,只不过接口之间逗号隔开
3、 接口甚至还可以单继承的同时多实现
import java.io.Reader;
public class Test_Interface3 {
public static void main(String[] args) {
//2,左侧写的接口到底是谁?--要看你想用哪个接口的功能,左侧就写谁
Inter2 in = new Inter2Impl() ;
in.save();//数据保存成功!
int rows = in.update(2) ;//数据已经更新
System.out.println(rows);//5
System.out.println( in.update(2) );//数据已经更新
//5
in.delete("jack");//删除记录成功!jack
}
}
interface Inter1{
void save();
int update(int id);
}
interface Inter3{
void delete(String name);
}
//1,接口间是继承关系,而且可以多继承
interface Inter2 extends Inter1 , Inter3{
}
//4,实现类和接口,是实现关系,还可以多实现
class Inter3Impl implements Inter3 , Inter1 {
public void delete(String name) {
System.out.println("删除成功!");
}
public void save() {
System.out.println("保存成功!");
}
public int update(int id) {
System.out.println("更新成功!");
return 5;
}
}
//5,实现类可以在单根继承的同时,多实现
//Inter4Impl需要重写Inter1和Inter3里的 所有抽象方法,否则就是一个抽象类
abstract class Inter4Impl extends Object implements Inter1 , Inter3{
}
//3,实现类,实现了接口.需要把接口里 所有抽象方法都重写.
//Inter2接口里的3个方法都要重写
class Inter2Impl implements Inter2{
@Override
public void delete(String name) {
System.out.println("删除记录成功!"+name);
}
@Override
public void save() {
System.out.println("数据保存成功!");
}
@Override
public int update(int id) {
System.out.println("数据已经更新");
return 5;
}
}
抽象类和接口的区别
相同点
1、 都可以出现抽象方法
2、 都不能被实例化
3、 都需要子类重写抽象方法
4、 接口和抽象类体现了继承结构里的抽象层
不同点
1、 抽象类里有构造方法,用来给子类创建对象.接口里没有构造方法.
2、 抽象类里有变量,但是接口里,只有常量,会为简写的常量自动拼接public static final
3、 抽象类里有普通方法,但是接口里,都是抽象方法(除了jdk1.8)
4、 接口里的抽象可以简写,会为简写的抽象方法自动拼接public abstract
5、 抽象类只能是和子类之间发生单根继承关系
6、 接口和实现类之间是实现关系,而且可以多实现
7、 接口和接口之间是继承关系,而且可以多继承
8、 接口是为了突破java单继承的局限性来的
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。