private:私有的 只有本类当中可以访问
(default):默认的 只有本包(目录)当中可以访问
protected:受保护的 本包当中可以访问 包外有继承关系的子类中可以访问
public:公开的 谁都可以访问
各自能修饰哪些东西?
类 成员(属性 方法)
public T T
protected F T
(default) T T
private F T
面试题:A类里面定义一个public修饰的方法,那么在B类里面能不能访问?
需要先看A类能不能正常访问,如果A类可以正常访问,那么里面的公共方法都可以正常被访问
static
静态的 修饰符 相当于汉文中的形容词
static能修饰哪些东西?
1.属性:表示静态属性
静态属性表示整个类型共享一份的属性,不是每个对象都有一份的属性
--------------------------
public class TestStatic01 {
public static void main(String[] args){
Student stu1 = new Student("Tomcmd",24);
Student stu2 = new Student("汪亮",22);
stu1.country = "富强的中国";//静态属性可以直接用 类名. 来调用 Student.country
System.out.println(stu1.country);
System.out.println(stu2.country);
}
}
class Student{
String name;//每个学生都有名字,都有年龄
int age;
static String country; //教室里面的学生都来自中国
public Student(String name,int age){
this.name = name;
this.age = age;
country = "中国";
}
}
--------------------------
静态属性可以直接用类名调用
--------------------------
public class TestStatic02 {
public static void main(String[] args){
A a = new A();
System.out.println(a.x);
System.out.println(A.y);
}
}
class A{
int x = 45;
static int y = 50;
}
--------------------------
普通属性(没有用static修饰的属性),表示每个对象都有一份的属性,依赖于对象而存在,需要拿着对象去调用
面试题:
1.java中变量的概念大,还是属性的概念大?
答:变量,属性指的是成员变量,而变量除了包括成员变量,还包括局部变量
2.static为什么不能修饰局部变量?*******
static修饰局部变量的话,底层可以写成定义静态变量,和静态代码块初始化静态变量两部分,静态代码块在加载类时
就会去执行,但是局部变量需要在调用方法的时候内存空间才会存在,这两个时间点不一样,所以会报错
System.out ->中的out属性就是用static修饰的
2.方法:表示静态方法
需要拿着类名去调用,静态方法里面只能直接访问静态成员
Math.random()
Arrays.sort()
System.currentTimeMillis()
面试题:
1.普通方法调用起来简单,还是静态方法调用起来简单?
答:静态方法
2.既然静态方法调用起来简单,那么为什么不把一个类中的所有方法都定义成静态方法呢?
答:静态方法虽然用起来简单,但是静态方法里面访问的东西比较有局限性,静态方法里面只能直接
访问静态成员,如果想要在静态的方法里面访问非静态的成员,需要先创建对象,然后用对象去访问
--------------------------
public class TestStatic03 {
public static void main(String[] args){
B b = new B();
b.test();
B.show();
}
}
class B{
public void test(){
System.out.println("B类中的普通方法");
}
public static void show(){
System.out.println("B类中的静态方法");
}
}
--------------------------
public class TestStatic04 {
public static void main(String[] args){
C c = new C();
c.test();
C.show();
}
}
class C{
int x = 40;//普通属性:依赖于对象而存在
static int y = 55;//静态属性:不依赖于对象而存在
/**
普通方法:
优势:普通方法里面既可以直接访问静态成员,又可以直接访问非静态成员
劣势:调用起来比较麻烦,必须先创建对象,拿着对象去调用
*/
public void test(){
//代码执行到这一行,说明内存中已经有该对象了
//this表示调用test()方法的对象
System.out.println(this.x);
System.out.println(y);
}
/**
静态方法:
优势:调用起来比较方便,可以直接拿类名去调用
劣势:静态方法里面只能直接调用静态成员,如果想要调用非静态成员,需要先创建对象,拿着对象去调用
*/
public static void show(){//静态方法,不依赖于对象而存在
//代码执行到这一行,不能保证内存里面一定有C对象,但是
//x属性必须要依赖对象而存在,所以需要创建对象才能使用
C cc = new C();
System.out.println(cc.x);
System.out.println(y);
}
}
--------------------------
3.代码块:初始化一个普通属性
当我们想要初始化一个静态属性的时候,需要用静态代码块
普通代码块什么时候执行?
普通代码块是用来给普通属性进行赋值的,普通属性是每个对象都有的一个属性,所以普通代码块是创建对象的时候执行
创建几个对象,执行几次
--------------------------
public class TestStatic05 {
public static void main(String[] args){
}
}
class D{
int x;
x = 18; //报错
}
--------------------------
注意:类体里面不能写语句,语句写在方法体里面,这里的 x=18是赋值语句,所以报错,应该改为int x = 18;那为啥这样就不会报错呢?
//int x = 18;在底层是如下实现的:
int x;
{
x = 18;
}
--------------------------
public class TestStatic06 {
public static void main(String[] args){
D d = new D();
D dd = new D();
D ddd = new D();
System.out.println(d.x);
System.out.println(dd.x);
System.out.println(ddd.x);
}
}
class D{
//int x = 18;
int x;
//每次创建对象的时候执行,创建了几个对象就执行几次
{//初始化一个普通属性
x = 18;
System.out.println("执行了吗");
}
}
--------------------------
打印结果:
执行了吗
执行了吗
执行了吗
18
18
18
静态代码块什么时候执行?static{}
静态代码块是用来初始化静态属性的,静态属性整个类型共享一份,所以静态代码块只当
类第一次被加载的时候执行,且只执行一次
--------------------------
public class TestStatic06 {
public static void main(String[] args){
System.out.println(E.x);
System.out.println(E.x);
System.out.println(E.x);
}
}
class E{
//static int x = 10;底层是如下实现的
static int x;
static{//当我们给静态属性赋值的时候需要使用静态代码块
x = 10;
System.out.println("执行了吗");
}
}
--------------------------
打印结果:
执行了吗
10
10
10
代码块还以控制一个变量的消亡时间,也就是控制变量的作用范围
-------------------------
public class TestStatic07 {
public static void main(String[] args){
{ //代码块控制一个变量的消亡时间
int x = 1;
while(x <= 100){
System.out.println(x);
x++;
}
}
System.out.println(x); //报错,无法访问x
}
}
单例模式
模式:java中本没有模式的概念,用的程序员多了,也便有了模式----周树人
单例模式:一个类型只能(有且只有)有一个对象
1.私有化构造方法
2.创建一个私有的 静态的 属于本类类型的对象
3.创建一个公共的 静态的 返回本类类型对象的方法
----------------------
public class TestDanli01 {
public static void main(String[] args){
Sun s1 = Sun.getSun();
Sun s2 = Sun.getSun();
System.out.println(s1 == s2);//打印true
}
}
//单例模式:醉汉式
class Sun{
private Sun(){}
//这里之所以要加static修饰,是因为这里可以把sun看成Sun对象的属性,创建sun对象时,堆内存里面开辟空间,
//创建Sun对象,Sun对象里面要装属性,而属性又是Sun对象,所以存储的是另一个Sun对象的地址,这样就死循环了
//加上static就可以让整个Sun类型共用一个Sun对象
private static Sun sun = new Sun();
public static Sun getSun(){
return sun;
}
}
//懒汉式(这里还不完善,还需要考虑线程安全,这里不做讨论)
class Moon{
private Moon(){}
private static Moon moon;
public static Moon getMoon(){
if(moon == null)
moon = new Moon();
return moon;
}
}
----------------------
public class TestDanLi02 {
public static void main(String[] args){
Teacher tea = Teacher.getTea();
System.out.println(tea.name);
}
}
class Teacher{ //将其改为单例模式
String name;
int age;
//私有化构造方法
private Teacher(String name,int age){
this.name = name;
this.age = age;
}
//创建一个私有的 静态的 属于本类类型的对象
private static Teacher tea = new Teacher("二爷",22);
public static Teacher getTea(){
return tea;
}
}
----------------------
final
最终的 修饰符 相当于汉文中的形容词
final能修饰哪些东西? 类 方法 变量
1.类:最终类 "骡子"类
特点:不能派生类 但是可以有父类
----------------------
public class TestFinal01 {
public static void main(String[] args){
}
}
class A{}
final class B extends A{}
class C extends B{}//报错,final修饰的类不能被继承
----------------------
面试题:
String类和Math类底层都是用final进行修饰,为什么?
String类表示字符串类,在项目开发过程中是非常基础,非常核心的一个类,越是基础,越是核心的
类,所有的程序员都应该保持一致。如果不用final进行修饰,那么每个人都可以继承String类,并对其中的方法进行覆写
Math类里面定义的都是一些公理、定理,不能按照程序员的意愿进行修改,所以要用final进行修饰
2.方法:最终方法
特点:不能被覆盖,可以正常的被继承
Sun公司不在乎有多少人通过继承得到最终方法,但是需要保证的是,这个方法一定是最终版本,不能被修改
----------------------
public class TestFinal02 {
public static void main(String[] args){
BB bb = new BB();
bb.test();//打印 A类的最终方法
}
}
class AA{
public final void test(){
System.out.println("A类的最终方法");
}
}
class BB extends AA{
//test
}
-----------------------
3.变量 最终变量 常量
特点:一旦赋值了之后,就不能再改值
final修饰的是基本数据类型,值不能再改变
final修饰的是引用数据类型,地址不能再改变
final double pi = 3.1415926
-----------------------
public class TestFinal03 {
public static void main(String[] args){
final int x = 50;
x = 40; //报错,final修饰的基本数据类型值不能再改变
}
}
class Police{
String name;
int age;
public Police(String name,int age){
this.name = name;
this.age = age;
}
}
-----------------------
public class TestFinal03 {
public static void main(String[] args){
final Police p = new Police("张三",22);
p.name = "张三丰";
System.out.println(p.name);//打印 张三丰
//这里如果p = new Police("张三丰",22);打印会报错,因为p的地址改变了
}
}
class Police{
String name;
int age;
public Police(String name,int age){
this.name = name;
this.age = age;
}
}
----------------------
abstract
抽象的 修饰符 相当于汉文中的形容词
abstract能修饰哪些东西? 类 方法
1.类 抽象类,表示这个类型不形象不具体
特点:抽象类不能创建对象
面试题:
1.抽象类是类么?
是
2.抽象类有构造方法么?
有,任何类都有构造方法
3.抽象类是类,有构造方法,但是不能创建对象,那么他的构造方法有什么存在的意义?
抽象类的构造方法是为了给子类的super()去调用
----------------------
public class TestAbstract01 {
public static void main(String[] args){
Animal aa = new Animal();
}
}
abstract class Animal{
//public Animal(){} 只要是个类就一定有构造方法
public void eat(){
System.out.println("动物吃食物");
}
}
class Cat extends Animal{
public Cat(){
//super();
}
}
--------------------
2.方法:抽象方法 表示这个类型一定会这个方法,但是具体怎么执行,待留给子类去实现
特点:不能有方法体 直接的();结束
*:抽象类里既可以定义抽象方法,还可以定义普通方法
*:一个类里面只要出现了抽象方法,那么这个类就一定需要定义成抽象类
--------------------
public class TestAbstract02 {
public static void main(String[] args){
Dog dd = new Dog();
dd.eat();
}
}
abstract class Animal{
public abstract void eat();
}
abstract class Cat extends Animal{
//eat() -> abstract
}
class Dog extends Animal{
@Override
public void eat(){
System.out.println("狗啃骨头");
}
}
---------------------
接口
interface 相当于工业生产中的规范(第二大类型)
class interface enum @interface
类 接口 枚举 注解
四大类型都可以在编译之后生成.class文件
如何定义接口:
interface XXX{
//属性:数据类型 变量名 = 值;
//接口里面定义的属性默认加上三个修饰符
//public static final
int x = 9;
//方法:返回类型 + 方法签名();
//接口里面定义的方法默认加上两个修饰符
//public abstract
void test();
}
------------------------
public class TestInterFace01 {
public static void main(String[] args){
//接口不能创建对象
USBKeyBoard ukb = new USBKeyBoard();
USBMouse um = new USBMouse();
Computer c = new Computer();
c.open(ukb);
c.open(um);
}
}
/**
先开发规范类型 -> interface -> USB
找到一个类型的开发满足规范 -> USBKeyBoard USBMouse
找到一个类型的开发使用规范 -> Computer
*/
//制定所有USB设备必须具备的东西
interface USB{ //声明一个USB接口
//属性:对象有什么
//接口里面定义的属性默认加上三个修饰符
//public static final
int v = 5;
//方法:对象会什么
//返回类型 + 方法签名(方法名+参数)
//接口里面定义的方法默认加上两个修饰符
//public abstract
void connect();//表示每个USB设备连接的方法不同,但是具体怎么连接,每一个USB设备连接的方法不同,所以现在给不出具体的实现,待留给子类实现
}
//类 extends 类
//类 implements 接口
class USBKeyBoard implements USB{ //is a 是一个 是一种
//当我们拿着一个类去实现一个接口的时候,需要在这个类里面给出接口所有抽象方法的具体实现
@Override //jdk6.0之后
public void connect(){
System.out.println("USB键盘与电脑连接的方法");
}
}
class USBMouse implements USB{
@Override
public void connect(){
System.out.println("USB鼠标与电脑连接的方法");
}
}
class Computer{
public void open(USB usb){ //多态
usb.connect();
System.out.println("电脑正确的打开连接");
}
}
----------------
*:类和类之间的关系:extends
类和接口之间的关系:implements
接口与接口之间的关系:extends
java中的类只允许单根继承(如果可以多重继承,那么多个父类中如果出现相同的方法,子类应该继承谁的方法?所以只允许单根继承)
java中的接口可以多重继承(多重继承只是累计,不会具体实现,所以可以多重继承)
java中可以继承一个类的同时,还可以实现多个接口
*:当我们拿着一个类去implements一个接口的时候,需要给出接口里面所有抽象方法的具体实现
*:当方法覆盖的时候,可以加上@Override
当类和类之间的方法覆盖 jdk5.0开始可以加上@Override
当类和接口之间的方法覆盖 jdk6.0开始可以加上@Override
*:接口不允许创建对象
面试题:
抽象类和接口之间的区别?*************
1.表示的东西不一样
抽象类:abstract class 表示不具体的类
接口:interface 表示一种规范
2.定义属性不一样
抽象类:int x = 18;默认定义的是普通属性
接口:int x = 18;默认省略public static final
3.定义方法不一样
抽象类:抽象类中可以定义抽象方法,也可以定义普通方法
接口:接口中只能定义抽象方法;默认省略public abstract