#计算机基础
第22行b1+一个整型得到的数值类型自动转化为容量更大得整型,所以用byte做赋值不对
128超过了127,强制转化为更低的类型时,会溢出变为负数
12.3没有加 f 默认为double类型,所以要强制类型转换将double型转化为容量更低的类型
char数组类型默认初始化值为 ASC码值0,控制台表现为空格,不是转义字符空格符或‘0’
数组元素如果是引用类型(类似于string),或者本身数组为一个整型的二维数组,比如这样 new Arr[4][] 的数组,因为数组本身为引用类型,二维数组可以看成一个数组里面嵌套了另一个数组,所以其外部元素默认初始化值为null,调用内部元素的时候会报错空指针异常
栈中存的是数组中首个数组元素得首地址,堆中存的是new出来的结构
如果栈中没有指针指向堆空间中,这部分空间将会被 引用计数算法 回收
假如new出来得是一个整形int的二维数组,其内部元素默认初始化数值为0,外部元素得打印出来是里面嵌套的数组得的首地址
show()方法掉用结束后,因为a作为局部变量存在栈中,依次将a弹出.c1与c2作为局部变量在main方法中,所以也存在栈中,当main方法结束以后,依次将c2与c1弹出栈,由于在堆中c1与c2的属性框框没有栈的指针指向其中,则被垃圾回收
//反转数组
public void reverse(int[] arr)
{
int temp = 0;
for(int i = 0;i<arr.length/2;i++)
{
int temp = arr[i];
arr[i] = arr[arr.length-1-i];
arr[arr.length-1-i] = temp;
}
}
public void show(String a) //有确定个数的形参优先调用有确定个数的函数
{
System.out.println(“…”)
}
public void show(String … b)
{
System.out.println(“…”)
}
在swap函数中sysout打印m与n的数值打印出来的数值是交换后的数值
但是在main方法中打印出来的m与n是交换之前的m,n的数值,因为sysout是在swap函数后面的,此时swap函数已经执行完成,在内存中swap函数代码块内的变量已无效,所以m与n是交换之前的10和20
但是在main方法中打印出来的m与n是交换之前的m,n的数值,因为sysout是在swap函数后面的,此时swap函数已经执行完成,在内存中swap函数代码块内的变量已无效,栈空间中swap代码块变量被弹出. 所以m与n是交换之前的10和20
package com.at.guigu.java1;
public class ValueTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Data data = new Data();
data.m = 10;
data.n = 20;
ValueTest test = new ValueTest();
test.swap(data);
System.out.println("data.m:"+data.m+"data.n:"+data.n);
}
public void swap(Data data)
{
int temp = data.m;
data.m = data.n;
data.n = temp;
}
}
在swap函数代码块结束后,temp与data:0x7788出栈,此时栈内还有一个data:0x7788的引用类型指针指向堆空间,则堆空间内更换过后的属性不会被回收,所以输出表现为更换过后的数值,关键就在于传入引用数据类型,才会有指针指向堆空间中的data所在的区域
package com.at.guigu.java1;
public class Sort {
public static void main(String[] args) {
// TODO Auto-generated method stub
}
//冒泡排序
public void sortA(int[] Arr)
{
for(int i = 0;i<Arr.length-1;i++)
{
for(int j = 0;j<Arr.length-1-i;j++)
{
if(Arr[j]>Arr[j+1])
{
//错误的:
//swap(Arr[j],Arr[j+1]);
//正确的
swap(Arr,j,j+1);
}
}
}
}
public void swap(int[] Arr,int i,int j)
{
int temp = Arr[i];
Arr[i] = Arr[j];
Arr[j] = temp;
}
// public void swap(int Arr,int arr)
// {
// int temp = Arr;
// Arr = arr;
// arr = temp;
// }
}
value类的i初始值为15.在first函数的sysout输出结果中打印出的是20,因为此时second函数代码块已结束,内部变量已被回收,所以打印出的值为堆中第二个地址中的v.i
错误写法的问题是arr[0]的数值,经过第一次赋值发生了变化,导致利用arr[0]的后面的赋值也受到影响,所以可以采用倒序方式
System.exit(0);结束程序
打印arr打印出的是地址值,而打印arr1打印出的是abc。原因在于源码中println函数的重载传入char数组是进行了遍历的,而传入int型数组传入的是object类,返回的是未遍历的地址值
package com.at.guigu.exer;
public class Circle {
double radius;
public double findArea()
{
return Math.PIradiusradius;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package com.at.guigu.exer;
public class passObject {
public static void main(String[] args) {
// TODO Auto-generated method stub
passObject pass = new passObject();
Circle c = new Circle();
pass.testObject(c, 5);
}
public void testObject(Circle c ,int times)
{
System.out.println("radius\t\tArea");
for(int i = 1;i<=times;i++)
{
c.radius = i;//这里没有构造器需要赋值
System.out.println(i+"\t\t"+c.findArea());
}
}
}
package com.at.guigu.exer;
public class passObject {
public static void main(String[] args) {
// TODO Auto-generated method stub
passObject pass = new passObject();
Circle c = new Circle();
pass.testObject(c, 5);
System.out.println("now radius is"+"\t\t"+c.radius);//其实这里考察的是第九行传入的是不是引用类型,只有传入引用类型c.radius才会被修改而不是0
}
public void testObject(Circle c ,int times)
{
System.out.println("radius\t\tArea");
for(int i = 1;i<=times;i++)
{
c.radius = i;//这里没有构造器需要赋值
System.out.println(i+"\t\t"+c.findArea());//“\t\t”代表制表符
}
}
}
匿名对象:
//匿名对象的用法,实际应用场景
PhoneMall mall = new PhoneMall();
mall.show(new phone()); //匿名对象只能使用一次,所以在被作为形参传入的show函数中会被调用两次
class PhoneMall()
{
public void show(Phone phone)
{
phone.sendEmail();
phone.playGame();
}
}
这两种写法不能同时存在:
java中的参数传递机制:值传递机制
为什么此题中最后打印出的s1仍然是“hello”??
String类型的“Hello”被存在的位置是常量池,是以char数组的形式进行存储的不可以被改变。而s形参被s1实参赋值以后,指向常量池中的“hi”,s1指向的“Hello”仍然没有被改变
public class Animal {
String name;
private int age; //对象的年龄不应该对用户直接公开,用private权限修饰符
public void setAge(int l) //设置接口,接口中应存在对于age的限制
{
if(l%2==0&&l>0)
{
this.age = l;
}
else
{
this.age = 0;
}
}
public int getAge()
{
return this.age;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
public class AnimalTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
AnimalTest test = new AnimalTest();
Animal ani = new Animal(); //如果没有显示定义一个构造器,则系统默认提供一个构造器new后面的Animal()就是系统提供的构造器
ani.setAge(6);
ani.name = "lucky";
}
}
显示初始化是指可以在了类里面声明的属性位置上直接进行赋值
构造器中调用其他构造器要将 this();放在第一行
构造器也可以完成重载以及内部的复用
public Animal() {
}
public Animal(String name, int age) {
this();
this.name = name;
this.age = age;
}
public int getAge()
{
return this.age;
}
public void marry(Boy boy)
{
Boy.marry(this);
}
如果想调用两个重名但是不同包下的accout类,则可以一个直接正常的实例化对象,一个则需要全类名的方式去实例化:包.类名 acc1 = new…代表的就是引入这个包下的那个类
java下的两种Date类:
引入一个包的 .* 与引入这个包的子包下的类需要分别引入
如果import引入static静态的,最后的落脚点一定是结构,可以是 .* ,如上所示:
如果import引入static静态的,最后的落脚点一定是属性或方法,比如下面程序中的 out(属性),round(方法)都可以前面不加System或Math直接使用。最后是 .* ,如上所示
如果将构造器私有化,则只能产生一个对象(单例模式)
java中一个类一定要有构造器,即使是反射其内部也存在构造器
java默认提供的构造器,其构造器的权限都与类的权限修饰符是一致的
子类继承自父类后,子类可以获取了父类中私有的结构,但由于封装性(私有)的影响,其子类不能调用这个私有的结构
继承的父类中的属性是私有的,但其中要有public的get与set方法便于子类继承以后对父类中继承过来的私有属性进行get与set方法的赋值操作
这里findVolume方法中调用的findArea方法是其父类中继承得到的结构,所以可以拿过来直接调用
子类重写父类的方法,子类的权限修饰符应>=的父类权限修饰符(记:烙饼,烙第二张要盖住第一张)。若父类的方法权限修饰符为private时,子类不可以重写父类中的这个私有的方法
父类被重写的方法的返回值对象若为引用类型,则子类重写方法的的返回值类型可以与父类返回值类型相同也可以为父类返回值类型的子类
在子类重写了父类的方法以后若还想调用父类中未被重写的方法,如图直接使用super.findArea()调用父类中方法
super有点类似于this
这里子类与父类中都有id这个属性,如果子类与父类中有相同的属性,但想调用父类中的id,可以使用super.id。正常情况下如果前面不加上this或super,程序会优先查找子类中有没有这个属性,再接着寻找父类中有没有这个属性。
为什么只实例化了Cylinder对象(调用了Cylinder的无参构造器),却依然能够求出圆柱的表面积?因为Cylinde继承自Circle,Cylinder的无参构造器中第一行已经隐含了super(),所以依然可以调用其父类的构造器
或者我们将Cylinder的父类Circle的空参构造器注释掉,其子类的空参构造器就会报错,因为其子类空参构造器第一行隐含了super()是调用的其父类的空参构造器
这里checkAccount中如果没有构造器会报错,因为这个子类继承了父类,父类中只有一个有参数的构造器,子类中如果没有设置构造器会被默认是无参构造器–super(),而父类中只有一个有参数的构造器,就会默认没有无参构造器所以会报错
红框中对余额的修改是正确的,可以使用setBalance(getBalance()-amount);来设置余额。但一般的账户类中可能没有设置余额方法,所以可以使用super.withdraw(amount);调用父类中withdraw方法来调整余额。
圆圈里小心的是 super. 不能丢了,丢了就递归出不去了
this()与super()都应该出现在构造器中第一行,意思是本类的构造器与其父类的构造器
多态性一定要伴随方法的重写,多态性可调用的方法的种类只能是左侧父类中方法的种类,执行是右侧子类的已重写的方法
package animalTest;
public class Animal {
public void eat()
{
System.out.println("动物吃东西");
}
public void shout()
{
System.out.println("动物叫");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package animalTest;
public class AnimalTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Animal ani = new Dog();
AnimalTest test = new AnimalTest();
test.func(ani);
}
public void func(Animal ani) //多态性的应用,这里避免了重载,是哪个对象就去执行那个方法
{
ani.eat();
ani.shout();
}
}
package animalTest;
public class Dog extends Animal{
public void eat()
{
System.out.println(“狗吃肉”);
}
public void shout()
{
System.out.println(“汪汪汪”);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
例子二类似于equals这个传入方法
例子三可以传入多种数据库类型,但方法体其中进行的操作是一致的
Animal ani = new Dog(); 如果涉及到调用ani的属性值,而 Animal 与Dog对象属性值不同,则调用的是其父类Animal的属性值
可以理解成多态只是多了子类所重写的方法
this()与super()在首行,必须二选一。要么this()在首行,要么super()在首行。如果都没有就默认是super()在首行
@前面为父类类型@后面为地址值,这里是由于将p2向下转型cast以后,@前面的类型的限制就没有了,对空间中原本加载好的子类的方法就可以被调用了。
使用向下类型转换也可能出现异常,比方说这里转换前person类的p2里面装的是man类型,向下类型转换不可以转换为woman类型
Person p1 = new Man();
Person p1 = new Man();
if(p1 instanceof woman)
{
Woman w1 = ( Woman)p1;
w1.goShopping();
}
例子二不会通过,想要向下转型(Man)成功,p4里装的一定是一个Man的类,如果本身就是父类则不会成功,因为p4其中也没有子类Man的方法
public void method(Person p1)
{
String info = p1.getInfo();//getInfo是Man与Woman两个类中的方法,p1可以进行动态绑定
System.out.println(info);
if(p1 instanceof Man)
{
System.out.println(“1”);
}
if(p1 instanceof Woman)
{
System.out.println(“2”);
}
}
![在这里插入图片描述](https://img-blog.csdnimg.cn/0a4e5880deab4aa1803a38393a7d1fed.JPG?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA6Iul6aOOMTk5Nw==,size_20,color_FFFFFF,t_70,g_se,x_16道题test类中给出的是Base1 base = new Sub1( )(形参列表可以看成相同是因为 int… arr这个可变形参是jdk新特性,可变形参与int [ ]arr可以认为相同,不能同时存在)
上图,(形参列表可以看成相同是因为 int… arr这个可变形参是jdk新特性,可变形参与int [ ]arr可的参数表以认为相同,不能同时存在),所以这三个方法只能看成是add(a,int [ ]arr)被 add(a,int… arr)重写了。add( , , )不能重写add(a,int… arr),因为重写与被重写的方法必须保证参数表和函数名相同权限与返回类型可以不同。所以只能找父类中被重写的方法,所以输出仍然是sub_1
如果涉及到红框内的,输出只能是sub_2,由于s被cast了,所以不涉及到父类,子类应该看确定3个参数数量的方法
比方说任何类的构造器第一行都隐含一个super()
这里这两个例子其实new的是两个对象,地址值不同
//手动实现重写equals
//从两个方向考虑
//手动实现重写equals
//从两个方向考虑 1.地址是否相同 2.是否属于同一个类
//手动实现重写equals
//从两个方向考虑 1.地址是否相同 2.是否属于同一个类
public boolean equals(Object obj)
{
if(this == obj)
{
return true;
}
if(obj instanceof Customer)
{
Customer cust = (Customer)obj;
return this.age == cust.age && this.name.equals(cust.name);
}
}
obj instanceof Customer , 此时obj虽然是Object类,但仍然可以用它里面装的(Customer类)拿来判断是不是Customer类的对象
红框内可以理解成,x如果有equals方法证明它肯定不是null,所以任何x.equals(null)都是false。但是要注意 .equals()前面那个必须不能是null
进行“ == ”比较的前提是类型得一致
这里s1与s2相互进行“ == ”比较其实返回得还是true,因为String存在的位置是常量池中,常量池中如果再赋值一个值相同命名不同的变量(注意不是新new出来的)指向得依然是同一个地址(复用)
这里s1与s2相互进行“ == ”比较其实返回得还是true,因为String存在的位置是常量池中,常量池中如果再定义一个值相同命名不同的变量指向得依然是同一个地址(复用)。但如果使用new String(“”);方式去定义一个值相同得String对象,进行“==”就会返回false
蓝框中的类继承自Number类,number类继承自Object。Java中类将基本数据类型刨除在外,而有了包装类,基本数据类型就也可以当作正常得类来使用
public class WrapTest {
@Test
public void wraptest()
{
int num1 = 10;
Integer cnt = new Integer(num1);
System.out.println(cnt);
Integer amount = new Integer("10");
System.out.println(amount);
Integer amnt = new Integer("10abc"); //这种编译通过不了,如果Integer传入得形参是String类型,必须是一个数字
System.out.println(amount);
//Boolean bol = new Boolean(true);
//Boolean bol = new Boolean("true");
//Boolean bol = new Boolean("true110"); //这种编译能通过,但结果是false
}
@Test
public void test2() //将包装类转化成基本数据类型,调用包装类的Xxx.xxxValue()方法
{
Integer cunt = new Integer(10);
int cnt = cunt.intValue();
System.out.println(cnt);
}
@Test //JDK5.0新特性:自动拆箱装箱
public void test3()
{
int cnt = 3;
Integer cunt = cnt; //自动装箱
int amount = cunt; //自动拆箱
}
/ @Test //基本数据类型,包装类转化为String
// public void Test4()
// {
// int s1 = 10;
// String str = String.valueOf(s1); //相当于把s1自动装箱再取去出箱子中的value值
// }
@Test //String转化为基本数据类型
public void Test5()
{
String str = “123”;
int s = Integer.parseInt(str); //相当于把s1自动装箱再拆箱去出箱子中的value值
}
第一个箭头所指输出的是1.0 ,因为在三元运算符运算时,会将 :的两侧转化成为一个类型,,所以整型转化为double型,前面是true,结果为1.0 。第二个就不涉及到三元运算符就是1
Vector集合的addElement:
8.2的证明: 取一个随机数,编译的时候看不出来是哪个,只有运行时才知道
引用类型包括 类、数组、接口
如果s = null;下面第一个箭头处输出值为null(print函数中封装了如果为null类型则输出null的保护机制),第二个位置则会输出空指针异常
Static静态变量是随着类的加载而加载的,所以可以直接调用 类.静态变量比如 Chinese.country
Static方法里不能存在super或this关键字,因为Static的生命周期是伴随类去加载的先于对象加载的,而this与super指代的是当前对象与其父类对象是后于Static加载的。所以任何static方法与static属性前面都是类进行调用的(而不是this或super)如:Chinese.walk( ),Chinese.nation
工具类中的方法习惯于直接用类去调用,比如Math中的一些方法,没有必要去实例化对象去调用
package com.at.guigu.exer;
public class Circle {
double radius;
private int id;
private int total = 0;
private static int init = 1001 ;
public Circle()
{
id = init++; //每新创建一个圆,编号都加1
total++; //每新创建一个圆总数加1
}
public Circle(double radius)
{
this(); //需要维护两个属性,重载上面构造器
this.radius = radius;
}
public double findArea()
{
return Math.PIradiusradius;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
}
/**
* @return the total
*/
public int getTotal() {
return total;
}
/**
* @param total the total to set
*/
public void setTotal(int total) {
this.total = total;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Circle cir = new Circle ();
System.out.println(cir.id);
}
}
package com.at.guigu.exer;
class Bank {
private Bank()
{
}
private static Bank bk = new Bank();
public static Bank getBank()
{
return bk;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package com.at.guigu.exer;
public class BankTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Bank bk1 = Bank.getBank();
Bank bk2 = Bank.getBank();
System.out.println(bk1 == bk2);
}
}
单例的饿汉式实现:
package com.at.guigu.exer;
class Bank {
private Bank()
{
}
private static Bank bk = new Bank();
public static Bank getBank()
{
return bk;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package com.at.guigu.exer;
public class BankTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Bank bk1 = Bank.getBank();
Bank bk2 = Bank.getBank();
System.out.println(bk1 == bk2);
}
}
单例模式的懒汉式实现:
package com.at.guigu.exer;
class Bank {
private Bank()
{
}
private static Bank bk = null; //懒汉式实现
public static Bank getBank()
{
if(bk == null)
//if保证只能实例化一个对象,如果有一个则不能再有
{
bk = new Bank();
}
return bk;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package com.at.guigu.exer;
public class BankTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Bank bk1 = Bank.getBank();
Bank bk2 = Bank.getBank();
System.out.println(bk1 == bk2);
}
}
由父及子,静态先行。先输出的不是“777”,因为main作为入口要由类去调用main。而类需要先加载伴随static代码块加载,所以先调用static代码块中的输出,再调用main中方法,之后再由父及子的调用
final不能被其他类所继承或重写,其他类继承要extends就是扩展,但是final是“最终的”。final属性也不能使用set方法,构造器是实例化得最后一步,如果final变量已经被实例化以后,就不能再进行set修改了。如果final变量在这个类中是统一的就显式赋值,如果final变量不是统一的就用构造器,如果final变量在赋值之前要进行一些操作就用代码块
package com.at.guigu.exer;
public class FinalTest {
final int length;
final int width;
{
length = 3;
}
public FinalTest()
{
width = 4;
}
public FinalTest(int n) //final属性在构造器里也可以进行重载
{
width = n;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
定义final与static final属性的区别是,定义fianl属性可以使用构造器重载为多个实例化对象定义多个final值(例:身份证号),而static final属性只能该类中是所有对象共用一个相同属性值
调用工具类大多是采用静态的方法去调用,因为工具类没有必要通过new不同的对象去调用工具类中的方法
这种仍然算单例模式,因为这样定义即使public权限比私有更大了,也无法在外面做 类.属性的修改。
代码块是自动执行的(类或对象的创建时)不需要去自己调用
抽象类不能实例化,但是抽象类中可以有非抽象的方法,抽象类中也可以有构造器(有参无参都可以有),因为这个抽象类的子类的构造器的第一行有一个super()会自动调用父类的构造器。如果抽象类的子类继承了抽象类,则这个子类想要实例化对象,则必须要把里面继承到的父类的所有方法全部重写,如果没有重写就是还是存在抽象方法,抽象方法不能被实例化的调用,则这个子类也得是抽象的。包含抽象方法的类也必须是抽象类的原因同上。抽象方法 public abstract void walk()没有方法体(大括号)
计算这两个指标要根据具体交通工具,所以可以令父类声明为abstract方法,具体子类拿来重写
(抽象类,子类必须重写)与(私有,final,static)这些子类继承过来不能进行重写的关键字是死对头
static方法为什么不能重写?
可以理解成多态与重写是息息相关的,多态性中执行的重写操作进行的是编译以后的动态绑定,而static方法在编译时已经加载了下来是静态绑定,所以就不能再进行重写操作了
可以理解成具体调那个子类没有命名,但是子类里面该重写的方法应用的功能都写好了,但这个子类还是person这个父类的子类,所以method1(new Person(){ @Override public void eat(){ } })
package com.at.guigu.exer;
interface Flyable {
public static final int VIS = (int) 7.9;
final int K = 6; //接口中public static 可以省略
public abstract void fly() ;
void walk() ;
}
package com.at.guigu.exer;
public class Plane implements Flyable{
public static void main(String[] args) {
// TODO Auto-generated method stub
}
@Override
public void fly() {
// TODO Auto-generated method stub
}
@Override
public void walk() {
// TODO Auto-generated method stub
}
}
package com.at.guigu.exer;
public interface USB {
public abstract void start();
public abstract void end();
}
package com.at.guigu.exer;
public class Printer implements USB{
@Override
public void start() {
// TODO Auto-generated method stub
System.out.println(“打印机开始工作”);
}
@Override
public void end() {
// TODO Auto-generated method stub
System.out.println("打印机结束工作");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package com.at.guigu.exer;
public class Computer {
public void transferData(USB usb) //实现了接口的多态性
{
usb.start();
System.out.println("具体执行的操作");
usb.end();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package com.at.guigu.exer;
public class ComputerTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Computer com = new Computer();
com.transferData(new USB() { //3.创建了接口匿名实现类的匿名对象
@Override
public void start() {
// TODO Auto-generated method stub
System.out.println("123");
}
@Override
public void end() {
// TODO Auto-generated method stub
System.out.println("456");
}
});
USB phone = new USB() { //4.创建了接口非匿名实现类的匿名对象
@Override
public void start() {
// TODO Auto-generated method stub
System.out.println("789");
}
@Override
public void end() {
// TODO Auto-generated method stub
System.out.println("1234");
}
};
com.transferData(phone);
}
}
package com.at.guigu.exer;
public class Server implements NetWork{
public static void main(String[] args) {
// TODO Auto-generated method stub
}
@Override
public void browse() {
// TODO Auto-generated method stub
System.out.println("真实服务器访问网络");
}
}
package com.at.guigu.exer;
public class ProxyServer implements NetWork{
private Serve work;
public void check()
{
System.out.println(“检查成功”);
}
public ProxyServer(NetWork work) {
this.work = work;
}
@Override
public void browse() {
// TODO Auto-generated method stub
check();
work.browse();
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
package com.at.guigu.exer;
public interface NetWork {
public abstract void browse();
}
Factory体现的是创建者,专门创建对象的
错误在红框处因为Ball ball是public static final的变量
JDK8中接口的新特性:
package com.at.guigu.exer;
public interface CompareA {
public static void method1()
{
System.out.println(“123”);
}
public default void method2()
{
System.out.println(“456”);
}
}
package com.at.guigu.exer;
public class Subclass implements CompareA{
public void method2() //default方法只能定义在接口类中,但可以重写
{
System.out.println("789");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
package com.at.guigu.exer;
public class CompareAtest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Subclass s = new Subclass();
s.method2(); //default方法只能使用实例化对象去调用
CompareA.method1(); //接口中的static方法只能使用类去调用,不能使用实例化调用。类似于工具包,compare方法
}
}
类优先原则,在子类没有重写情况下。父类与接口中两个方法同名同参数,优先调用父类中方法
不管是继承父类方法还是实现了接口,都是优先调用子类重写的方法
单独调用接口中的默认方法:CompareA.super.method3();
内部类可以调用外部类的非静态属性,相当于Person.this.eat(); Person是外部类
成员内部类,就可以把他当成一个成员了,就可以用 static bird class{},private bird class{}
非静态内部类的实例化: Person p = new Person(); Person.Bird bird = p.new Bird();
静态内部类的实例化: Person.Dog dog = new Person.Dog();
如果发生了属性重名情况内部类调用外部类中属性的调用:System.out.println(Person.this.name);
public MyComparable getComparable()
{
class MyComparable implements comparable
{
@Override
public int comparTo(Object o)
{
return 0;
}
}
return new MyComparable();
}
局部内部类调用外部类属性: Person.this.age; 可以理解成this.age就是当前类对象的属性,Person.就可以认为是他们在这个外部类之中