JAVA面向对象(2)
一:代码块:
1)实例代码块,使用一个大括号,里面可以放一些语句和访问一些成员变量(定义在类中的代码块),也叫做构造代码块,一般用于初始化实例成员变量,当我们去new一个对象的时候,就会被执行了,可以初始化一个实例成员变量
public class TestDemo{public String name;public int age;public static String str;{this.name="李佳伟";//初始化实例成员变量this.age=90;}static {str="生命";//初始化静态成员变量this.name=""//报错}}2)静态代码块:
static{里面放一些字段和方法};在我们通过类名进行访问静态成员的时候,也会默认执行静态代码块的内容
public class TestDemo{public static int count=10;static {count=99;}public static void main(String[] args) {System.out.println(TestDemo.count);} } //打印结果是99 package Demo;public class TestDemo{static {count=99;}public static int count=10;public static void main(String[] args) {System.out.println(TestDemo.count);}} //打印结果是101)如果count没有进行初始化,那么在任何位置(定义count的位置和static代码块的位置)count的值都是static代码块的值
2)静态代码块的执行顺序>实例代码块的执行顺序,一般用于初始化静态成员变量,再进行类加在的时候就被调用了
package 李佳伟; import javax.swing.*; import java.security.PrivateKey; import java.util.Scanner; import java.util.Arrays; import java.util.Scanner; class Person//一个类 { public int age;public static int count=0;public Person()//无返回值类型声明,且必须与类名相同{System.out.println("我是构建方法");}{System.out.println("我是示例代码块");}static{count=99;//如果都是静态的,则初始化前看一看被定义的先后顺序this .age=18;不能进行访问,因为静态代码区不能访问实例变量,且this表示当前对象的引用System.out.println("我是静态代码块");}} public class HelloWorld {public static void main(String[] argv){Person lijiawei=new Person();//lijiawei就是一个对象,而且一个类可以面向多个对象}} //静态代码块>实例代码块>构造方法1)所以我们得出结论,对于静态代码快来说,无论生成多少个对象,静态代码块就只会执行一次,况且是最先执行的
2)静态代码块执行完毕后,实例代码块(构造快)再去执行,最后是构造方法执行,静态成员变量是类的属性,因此是在JVM加载类的时候开辟空间并进行初始化的
3)如果一个类中包含着多个静态代码块,在进行编译代码的时候,编译器会按照定义的先后顺序依次执行
4)实例代码块只有在创建对象的时候才会执行
5)上面的重写ToString方法把对象转化成字符串被称之为序列化
反序列化:将字符串转化成对象-----后面前后端进行交互的时候,讲一个字符串转化成JSON格式的数据
补充:
1)序列化最重要的作用:在传递和保存对象时.保证对象的完整性和可传递性。对象转换为有序字节流,以便在网络上传输或者保存在本地文件中
2)反序列化的最重要的作用:根据字节流中保存的对象状态及描述信息,通过反序列化重建对象。
3)核心作用就是对象状态的保存和重建。(整个过程核心点就是字节流中所保存的对象状态及描述信息)
class Person{public static int count=0;static{System.out.println("我是静态代码块");}public static void run(){System.out.println("我是run方法");} }System.out.println(Person.count); //最终打印的结果是我是静态代码块,0 对于toString方法来说,在调用println方法的时候会被自动调用JAVA的序列化和反序列化:
只有实现了Serializable或者Externalizable接口的类的对象才能被序列化为字节序列。(不是则会抛出异常)
JDK中序列化和反序列化的API: 1)java.io.ObjectInputStream:对象输入流 类的readObject()方法从输入流中读取字节序列,然后将字节序列反序列化为一个对象并返回。 2)java.io.ObjectOutputStream:对象输出流 该类的writeObject(Object obj)方法将将传入的obj对象进行序列化,把得到的字节序列写入到目标输出流中进行输出实现序列化和反序列化的实现:
1)若Student类仅仅实现了Serializable接口,并且还定义了readObject(ObjectInputStream in)和writeObject(ObjectOutputSteam out),则采用以下方式进行序列化与反序列化 2)ObjectOutputStream调用Student对象的writeObject(ObjectOutputStream out)的方法进行序列化。 3)ObjectInputStream会调用Student对象的readObject(ObjectInputStream in)的方法进行反序列化 1)若Student类实现了Externalnalizable接口,且Student类必须实现readExternal(ObjectInput in)和writeExternal(ObjectOutput out)方法,则按照以下方式进行序列化与反序列化。 2)ObjectOutputStream调用Student对象的writeExternal(ObjectOutput out))的方法进行序列化 3)ObjectInputStream会调用Student对象的readExternal(ObjectInput in)的方法进行反序列化1)Java有很多基础类已经实现了serializable接口,比如String,Vector等。但是也有一些没有实现serializable接口的;
2)static修饰字段不能被序列化
public class TestDemo{static class Student implements Serializable {public int age;public String name;public Student(int age,String name){this.age=age;this.name=name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Student{" +"age=" + age +", name='" + name + '\'' +'}';}}public static void main(String[] args) throws IOException, ClassNotFoundException { //1.序列化File file=new File("d:/textDemo.txt");FileOutputStream f1=new FileOutputStream(file);ObjectOutputStream outputStream=new ObjectOutputStream(f1);outputStream.writeObject(new Student(18,"hhhh")); //2反序列化FileInputStream f2= new FileInputStream(file);ObjectInputStream inputStream= new ObjectInputStream(f2);Student student2 = (Student) inputStream.readObject();System.out.println(student2);}练习1:编写一个类Calculator,有两个属性num1和num2这两个数据的值,不能在定义的时候进行初始化,最后实现加减乘除四种运算
package Demo; class Calculator{private int num1;private int num2;public void setNum1(int num1) {this.num1 = num1;}public void setNum2(int num2) {this.num2 = num2;}public int add(){return num1+num2;}public int sub(){return num1-num2;}public int mul(){return num1*num2;}public double dev(){return num1*1.0/num2;} } public class TestDemo{public static void main(String[] args) {Calculator calculator=new Calculator();calculator.setNum1(10);calculator.setNum2(20);System.out.println(calculator.add());System.out.println(calculator.sub());System.out.println(calculator.dev());System.out.println(calculator.mul());} }练习2:设计交换两个变量的值,要求交换实参的值
把实参的值放到我们的堆上,有地址就好了
public class TestDemo{public static void main(String[] args) {int a=10;int b=90;swap(a,b);System.out.println(a);System.out.println(b);}private static void swap(int a, int b) {int temp=a;a=b;b=temp;} } 无法交换解法:交换引用中属性的值
package Demo; class MyValue{public int data; } public class TestDemo{public static void main(String[] args) {MyValue myValue1=new MyValue();myValue1.data=90;MyValue myValue2=new MyValue();myValue2.data=100;swap(myValue1,myValue2);System.out.println("myValue1.data="+myValue1.data);System.out.println("MyValue2.data="+myValue2.data);}private static void swap(MyValue myValue1, MyValue myValue2) {int temp=myValue1.data;myValue1.data=myValue2.data;myValue2.data=temp;}}包:import是导入一个具体的类,而不能导入一个具体的包
1)是组织类的一种形式,是为了保证类的唯一性,假设你自己在代码中写了一个Test类,然后你的同事也写了一个Test类,那么就会导致代码无法编译通过
2)package:包,类所在的包,包是一组类的集合,可以防止类名冲突,import static可以导入一些静态方法,import可以导入一个具体的包,这是错的,只可以导入包中的一组类或者多组类;
3)import:引入,指引入了类所需要的类
import是导入包,以区别于同个名称的但是属于不同包的类;
4)在文件上方有一个字段是package,是将当前类导入到包中,等以后要使用的时候,可以使用import将其导入
5)正常情况下,有一个叫做java.util底下的包,他里面有一个package的字段,意思是把当前的类导入包中,以便后续的程序可以使用import来到如使用这个包里面的方法;
6)import java.util.Arrays这个意思就是导入java.util中的Arrays类
7)java.util.*,代表导入包中的所有的类,java在这个地方处理的时候,用谁就自动倒谁;
8)在C语言里面,是全部进行导入,一个类,在不同的包中有不同的内容
import java.util.Date;//导入包中的一个类,导入util包中的Date类 public class HelloWorld {public static void main(String[] args) {Date date=new Date();System.out.println(date.getTime());//打印的是一个毫秒级的时间戳} } public class HelloWorld {public static void main(String[] args) {java.util.Date date=new java.util.Date();System.out.println(date.getTime());} }我们需要使用java.util的其他类,我们就可以使用import java.util.*,这样我们就可以导入这个包的所有类,但是我们要注意并不是所有类都会被导入进来,而是用到谁我们就会倒入谁
但是我们有时候要显式指定我们要导入的类名,不然还是很容易会出现冲突的情况
一个包底下不能有相同的类,包名不一样,类名不一样,那么即使有相同的类也互不干扰
包名必须是小写字母
import java.util.*; import java.sql.*;public class HelloWorld {public static void main(String[] args) {Date date=new Date();System.out.println(date.getTime());} } 上面的代码会编译出错,我们应该这么写:因为是两个包里面都有一个Date类 import java.util.*; import java.sql.*; public class HelloWorld {public static void main(String[] args) {java.util.Date date=new java.util.Date();System.out.println(date.getTime());} } import static java.lang.Math.*; public class HelloWorld {public static void main(String[] args) {double x=30;double y=40;double result=sqrt(pow(x,2)+pow(y,2));System.out.println(result);} } 下面是另一种写法: import java.lang.Math; public class HelloWorld {public static void main(String[] args) {double x=30;double y=40;double result=Math.sqrt(Math.pow(x,2)+Math.pow(y,2));System.out.println(result);} } package Demo;import java.util.Date; import static java.lang.System.*; public class TestDemo{public static void main(String[] args) {out.println("生命在于运动");} }下面是我们经常使用的包:
1.java.lang:系统经常引入的基础类(String,Object),此包在JDK1.1之后进行自动导入
2.java.lang.reflect:java反射编程包
3.java.net:进行网络编程开发包
4.java.sql:进行数据库开发的支持包
5.java.util:是java提供的工具程序包,集合类等等
6.java.io:是IO编程开发包
包的访问权限控制:
当你的成员变量,不加任何的访问修饰限定符的时候,默认是一个包访问权限
1)不加任何的字段作用,相当于是default:默认是包访问权限:只能在同一个包中的相同类或者同一个包中的不同类使用和进行访问
只在包中使用 int a=10,这个变量不可以在包外使用,也就是说,这个变量只能在同一个包中的不同类进行使用和访问,例如如果是一个类,class Test{},他的前面也没有加任何的访问修饰限定符,所以他也只能在一个包中进行访问;只能在包内new,不可以在包外new;
2)加上public之后,就可以在包外进行访问了,同时在包内也可以使用,任何地方都可以进行访问
3)private:只可以在类中进行使用,在同一个包中的同一个类;
4)defalut:默认为在同一个包内可以访问,包外不能访问
只可以在同一个包中进行访问,同一个包中的同一个类,同一个包中的不同类都可以进行访问,别管是子类还是非子类,只要出现了不同的包中,就不可以进行访问;
5)protected:在同一个包中和public没有什么区别,它主要是体现在继承上面的,同一个包中的同一个类,同一个包中的不同类,以及不同包中的子类都可以进行访问;不同包中的非子类是不可以进行访问的(super.属性),不同包必须继承进行访问
总结
以上是生活随笔为你收集整理的JAVA面向对象(2)的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: torch.distributions.
- 下一篇: 关闭360WIFI登录认证